(部分)专门化依赖类型的非类型模板参数

iav*_*avr 26 c++ templates partial-specialization non-type

也许我累了,但我坚持这个简单的部分专业化,这不起作用,因为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>;
Run Code Online (Sandbox Code Playgroud)

更换0T(0),T{0}(T)0没有帮助.那么这种专业化甚至可能吗?

Con*_*tor 25

见标准的段落[temp.class.spec] 14.5.5/8:

与专用非类型参数对应的模板参数的类型不应取决于特化的参数.[ 例如:

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
Run Code Online (Sandbox Code Playgroud)

- 末端的例子 ]

编辑的答案:最简单的解决方法是使用类型1替换非类型模板参数:

#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>> {};
Run Code Online (Sandbox Code Playgroud)

  • @iavr gcc 如果您在专业化中将 `0` 转换为 `T`,则接受它:http://coliru.stacked-crooked.com/a/435ff04ca4640ae8 (2认同)

Sam*_*all 8

使用Yakk解决方案的解决方案:

#include <iostream>
#include <type_traits>

template <typename T, T N, typename = void > 
struct X {
  static const bool isZero = false;
};

template <typename T, T N>
struct X < T, N, typename std::enable_if<N == 0>::type > {
  static const bool isZero = true;
};

int main(int argc, char* argv[]) {
    std::cout << X <int, 0>::isZero << std::endl;
    std::cout << X <int, 1>::isZero << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

现场演示

  • 有意思的是,之前我还没有以这种方式使用`enable_if`.我在这里选择了一种不同的方法(参见编辑),但我会记住这一点,因为我猜它在检查一个或多个模板参数的任意条件时更通用. (2认同)

Yak*_*ont 5

您可以将typename=void参数添加到参数列表的末尾template,然后在专门化中使用std::enable_if_t<条件>