Search code examples
c++templatespartial-specializationnon-type

(Partially) specializing a non-type template parameter of dependent type


Maybe I'm tired, but I'm stuck with this simple partial specialization, which doesn't work because non-type template argument specializes a template parameter with dependent type 'T':

template <typename T, T N> struct X;
template <typename T>      struct X <T, 0>;

Replacing 0 by T(0), T{0} or (T)0 doesn't help. So is this specialization even possible?


Solution

  • See paragraph [temp.class.spec] 14.5.5/8 of the standard:

    The type of a template parameter corresponding to a specialized non-type argument shall not be dependent on a parameter of the specialization. [ Example:

    template <class T, T t> struct C {};
    template <class T> struct C<T, 1>; // error
    
    template< int X, int (*array_ptr)[X] > class A {};
    int array[5];
    template< int X > class A<X,&array> { }; // error
    

    —end example ]

    The answer to your edit: the easiest workaround is to replace a non-type template parameter with a type one:

    #include <type_traits>
    
    template <typename T, typename U>
    struct X_;
    
    template <typename T, T N>
    struct X_<T, std::integral_constant<T, N>> {};
    
    template <typename T>
    struct X_<T, std::integral_constant<T, 0>> {};
    
    template <typename T, T N>
    struct X : X_<T, std::integral_constant<T, N>> {};