我有这段代码,想要了解:
template <unsigned...>
struct sum;
template<unsigned size>
struct sum<size>
{
enum {value = size};
};
template<unsigned size, unsigned... sizes>
struct sum<size, sizes...>
{
enum { value = size + sum<sizes...>::value };
};
int _tmain(int argc, _TCHAR* argv[])
{
sum<1, 2>::value;
return 0;
}
我不明白为什么未实现的总和(取无符号......就像最后一个结构专门化,是不是存在冲突?)必须存在,以及如何使用模板部分中的相同参数来专门化和(e.g. sum<size, sizes...>
与template <unsigned size, sizes...>
相同。
为什么波纹管不起作用?
template<unsigned size>
struct sum
{
enum {value = size};
};
template<unsigned size, unsigned... sizes>
struct sum
{
enum { value = size + sum<sizes...>::value; };
};
答案 0 :(得分:7)
请注意,语法略有不同。声明主模板时:
template <unsigned...>
struct sum;
您不会在sum
之后提供模板参数。这是因为您正在创建一个全新的模板,并说它需要任意数量的无符号整数作为参数。
当你这样做时:
template<unsigned size, unsigned... sizes>
struct sum<size, sizes...>
{
enum { value = size + sum<sizes...>::value };
};
您正在专门化之前声明的模板。您要说的是,如果参数由无符号值后跟任意数量的其他无符号值组成,请使用此定义。这与主模板不完全相同。主模板包括零参数的可能性。
当你尝试这样做时:
template<unsigned size>
struct sum
{
enum { value = size };
};
template<unsigned size, unsigned... sizes>
struct sum // OOPS! A template called `sum` has already been declared!
{
enum { value = size + sum<sizes...>::value };
};
您正在尝试制作两个具有相同名称的不同类模板,这是不允许的。
请注意,这与功能模板的工作方式略有不同。使用函数模板,您可以执行重载,因此可以使用具有相同名称的多个函数模板。但是对于函数模板,您不能进行部分特化,因为这会产生很多歧义。
您可能认为主模板和专业化之间存在歧义,但更专业化的专业化总是优先于专业性较低的专业化,而主要模板始终被认为是最不专业化的。如果不是这样,那么部分专业化根本不起作用。
答案 1 :(得分:0)
第一个声明:
template<unsigned int... Ns>
struct sum;
是前向声明:它将模板声明为具有可变数量的unsigned int
参数的模板。
第一个特化是元函数的基本情况,它保留了variadic-pack只有一个参数的情况:
template<unsigned size>
struct sum<size>
{
enum {value = size};
};
第二个特化是递归的情况:它保留了variadic-pack至少有一个参数的情况:
template<unsigned size, unsigned... sizes>
struct sum<size, sizes...>
{
enum { value = size + sum<sizes...>::value };
};
我建议您在编写/学习模板元编程之前,先了解有关C ++模板机制(如即时,模板专业化等)的更多信息。
答案 2 :(得分:0)
借助c ++ 20的新功能,您可以解决如下问题:
通过许多参数初始化struct
:
template<int ...args>
您的结果将是const auto
。
static const auto value = (0 + ... + args);
auto
关键字是在c ++ 17中定义的,能够推断出函数的返回类型。
代码:
#include <iostream>
template<int ...args>
struct sum
{
static const auto value = (0 + ... + args);
};
int main(int argc, char *argv[])
{
const auto res = sum<10, 20, 40, -5>();
std::cout << "Result ";
std::cout << res.value;
std::cout << std::endl;
return 0;
}
结果:
Result 65