Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ (部分)专门化依赖类型的非类型模板参数_C++_Templates_Partial Specialization_Non Type - Fatal编程技术网

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 {};