template <typename X, typename Y> class A {
// Use Y::Q, a useful property, not used for specialization.
};
enum Property {P1,P2};
template <Property P> class B {};
class C {};
Is there any way to define a partial specialization of A
such that A<C, B<P1> >
would be A
's normal template, but A<C, B<P2> >
would be the specialization?
Edit in response to Marcelo: More specifically, the specialization should be chosen not just with B, but with any type that exhibits a certain property, for example that it's a template whose first argument is P2.
The goal is to use Y
to present a nice interface for A
, allowing to write something like A<C, Y<P2,Q> >
.
Replacing the Y
template parameter by a template template parameter would be nice, but is there a way to partially specialize it based on P
then?
The intention would be to write something like:
template <typename X, template <Property P> typename Y> class A {};
template <typename X> class A<X,template<> Y<P2> > {}; // <-- not valid
Edit in response to In silico: I said it would be nice to make Y
a template template parameter, but actually that defeats the purpose of what I wanted to do, which is to use Y
to group logically linked properties together, but still specialize A
based on one of those sub-properties.
Is there a way by adding traits to a specialization template <> class B<P2>
and then using SFINAE in A
? The intention would be to write something like:
template <> class B<P2> {
typedef int IAmP2;
};
// The following is not valid because it's a simple redefinition.
template <typename X, typename Y> class A {
// Substitution using this template would fail for Y<P1>, and only the
// general template would be left for selection.
typename Y::IAmP2 skipIfNotP2;
};