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;
};