也许我累了,但我仍然坚持这种简单的部分专业化,因为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>;
0
,T(0)
或T{0}
替换(T)0
并不起作用。那么这种专业化甚至可能吗?
答案 0 :(得分:23)
见标准的段落[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
- 示例]
编辑的答案:最简单的解决方法是使用类型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>> {};
答案 1 :(得分:7)
使用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;
}
答案 2 :(得分:3)
您可以在typename=void
参数列表的末尾添加template
参数,然后在专业化版中使用std::enable_if_t<
条件>
。[/ p>
答案 3 :(得分:0)
您需要在模板中传递一个整数值,如果类型T不是整数类型,则第一个和第二个模板都不起作用。
您可以将Traits作为类型化模板参数传递,以指定值N:
#include <iostream>
// error: ‘double’ is not a valid type for a template non-type parameter
template <typename T, T N> struct X0;
// error: ‘double’ is not a valid type for a template non-type parameter
template <typename T, T N, int = 0> struct X1;
template <typename T, T N>
struct IntegralTraits {
static constexpr T Value() { return N; }
};
template <typename T, typename Traits = void>
struct X2 {
static constexpr T Value() { return Traits::Value(); }
};
template <typename T>
struct X2<T, void> {
static constexpr T Value() { return T(); }
};
int main() {
// error: ‘double’ is not a valid type for a template non-type parameter
// X0<double, 0>();
// error: ‘double’ is not a valid type for a template non-type parameter
// X1<double, 0>();
X2<int> a;
X2<double, IntegralTraits<int, 1>> b;
std::cout.precision(2);
std::cout << std::fixed << a.Value() << ", "<< b.Value() << '\n';
return 0;
}
如果你将自己限制为整数类型,请选择一个大的:
template <typename T, std::size_t N = 0> struct X {};