somebody4
somebody4

Reputation: 515

c++, using enable_if along with existing template class?

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

Answers (2)

super
super

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

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.

Live Example

Upvotes: 1

Related Questions