Reputation: 515
I have existing template class A,B that cannot be changed.
template<class T>
struct A{static void F(){}};
template<int I>
struct B{};
I want to specialize A
only when T
is B<I>
and 1<=I<=5
.
If A can be changed, it would be like the following :
template<class T,class = void>//added second param
struct A{static void F(){}};
template<int I>
struct B{};
template<int I>
struct A< B<I>, std::enable_if_t<(1<=I&&I<=5)> >{static void F(){}};
int main(){
A<B<0>>::F();//call origin ver
A<B<1>>::F();//call specialized ver
A<B<10>>::F();//call origin ver
}
Is it possible?
Upvotes: 1
Views: 62
Reputation: 12928
Add one layer of indirection.
template <class T>
struct SpecializedA {
//... specialized implementation
};
template<class T,class = void>//added second param
struct MyA_impl{
using type = A<T>;
};
template<int I>
struct MyA_impl< B<I>, std::enable_if_t<(1<=I&&I<=5)> >{
using type = SpecializedA<B<I>>;
};
template <typename T>
using MyA = typename MyA_impl<T>::type;
With that we get
MyA<B<0>> == A<B<0>>
MyA<B<1>> == SpecializedA<B<1>>
MyA<int> == A<int>
Upvotes: 0
Reputation: 170044
You could redirect the specialization into inheriting from a conditional implementation
template<class T>
struct A{
static void F() { std::cout << "default\n"; }
};
template<int I>
struct B{};
struct tag{};
template<int I>
struct ABImpl {
static void F() { std::cout << "specialized for " << I << '\n'; }
};
template<int I>
struct A<B<I>> : std::conditional_t<1 <= I && I <= 5, ABImpl<I>, A<tag>> {};
The tag
is a dummy that' simply used for grabbing a default implementation without risk of conflict.
Upvotes: 1