Search code examples
c++templatessfinaeenable-if

Use enable_if with two levels of templating


I want to use enable_if to define a class for certain types. Among these types, I need to use some templated types, and I am unable to make it work. Here is a MWE:

The templated class A:

template<typename T, typename Enable = void> class A;

Its specialization for some simple types, such as integral types here, can be defined as follows:

template<typename T>
class A<T, std::enable_if<std::is_integral<T>::value>::type>
{ ... };

Now I define a bunch of templated types:

template<typename U> class X {...};
template<typename U> class Y {...};

How should I proceed to specialize my class A for types X and Y?

Two attempts that do not work:

  1. With the following, declaring a object of type A<X<int> > for instance yields an error incomplete type:

    template<typename U>
    template<typename T>
    class A<T, std::enable<std::is_same<T, X<U> >::value 
                        || std::is_same<T, Y<U> >::value>::type> 
    { ... };
    
  2. With the following, the error is 'T' is not a template.

    template<typename U>
    template<typename T>
    class A<T<U>, std::enable<std::is_same<T, X>::value 
                           || std::is_same<T, Y>::value>::type>
    { ... };
    

Solution

  • X and Y are class templates, not types. Your compiler is correctly complaining about using a type as a class template in you second example.

    If you want a specialization for them

    template<typename>
    class A;
    
    template<typename T>
    class A<X<T>> : A_for_XY<X<T>> {};
    
    template<typename T>
    class A<Y<T>> : A_for_XY<Y<T>> {};