C++ (部分)专门化依赖类型的非类型模板参数
也许我累了,但我还是坚持使用这个简单的部分专门化,它不起作用,因为C++ (部分)专门化依赖类型的非类型模板参数,c++,templates,partial-specialization,non-type,C++,Templates,Partial Specialization,Non Type,也许我累了,但我还是坚持使用这个简单的部分专门化,它不起作用,因为非类型模板参数专门化了一个依赖类型为“t”的模板参数。: template <typename T, T N> struct X; template <typename T> struct X <T, 0>; 模板结构X; 模板结构X; 将0替换为T(0),T{0}或(T)0没有帮助。那么这种专门化是否可能呢?参见本标准第14.5.5/8段[临时等级规范]: 与专用模板对应的模板参
非类型模板参数专门化了一个依赖类型为“t”的模板参数。
:
template <typename T, T N> struct X;
template <typename T> struct X <T, 0>;
模板结构X;
模板结构X;
将
0
替换为T(0)
,T{0}
或(T)0
没有帮助。那么这种专门化是否可能呢?参见本标准第14.5.5/8段[临时等级规范]:
与专用模板对应的模板参数的类型
非类型参数不应依赖于
专业化[示例:
模板结构C{};
模板结构C;//错误
模板A类{};
int数组[5];
模板类A{};//错误
-[结束示例]
编辑的答案是:最简单的解决方法是将非类型模板参数替换为类型模板参数:
#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>> {};
#包括
模板
结构X;
模板
结构X{};
模板
结构X{};
模板
结构X:X_{};
您可以在模板
参数列表的末尾添加一个typename=void
参数,然后在specializations中使用std::enable_if\t
。使用雅克解决方案的解决方案:
#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;
}
#包括
#包括
模板
结构X{
静态常数布尔为零=假;
};
模板
结构X{
静态常数布尔为零=真;
};
int main(int argc,char*argv[]){
std::cout您需要在模板中传递一个整数值,如果类型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;
}
#包括
//错误:“double”不是模板非类型参数的有效类型
模板结构X0;
//错误:“double”不是模板非类型参数的有效类型
模板结构X1;
模板
结构完整性特征{
静态constexpr T Value(){return N;}
};
模板
结构X2{
静态constexpr T Value(){return Traits::Value();}
};
模板
结构X2{
静态constexpr T Value(){return T();}
};
int main(){
//错误:“double”不是模板非类型参数的有效类型
//X0();
//错误:“double”不是模板非类型参数的有效类型
//X1();
x2a;
X2 b;
标准:计算精度(2);
谢谢。我找到了一个解决办法(请参阅编辑的问题)-有更好的想法吗?@iavr我编辑了我的答案,为您的编辑提供了解决方案。很好,我已经将此与我的第一次尝试结合起来,请参阅编辑的答案。我无法解释原因,但在您的解决方案中的一般定义和专门化之间。Clang效果很好。@iavr gcc接受它,如果您将0
转换为t
on:有趣的是,我以前没有这样使用过enable_if
。我在这里选择了不同的方法(请参见编辑),但我会记住这一点,因为我想它在检查一个或多个模板参数的任意条件时更通用。@iavr您的解决方案非常灵活,如果我是您,我可能会坚持使用它(当然有评论!)@iavr值得一提的是,我的解决方案使用指针,而你的EDIT 2解决方案不使用指针。但你可能不需要该功能。对,我在这里使用的是数字。但是如果肯定更通用,则启用。\u。不相关,但你可能会发现这很有趣。我非常重视你在这方面的想法:
#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 {};