4

我有这段代码,想了解:

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

3 回答 3

8

请注意,语法有点不同。当您声明主模板时:

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

您正在尝试使用相同的名称创建两个不同的类模板,这是不允许的。

请注意,这与函数模板的工作方式有些不同。使用函数模板,您可以进行重载,因此拥有多个同名的函数模板就可以了。但是,对于函数模板,您不能进行部分特化,因为这会产生很多歧义。

您可能认为主模板和特化之间存在歧义,但更特化的特化总是优先于不太特化的特化,并且主模板总是被认为是最不特化的。如果这不是真的,那么部分专业化将根本不起作用。

于 2013-09-07T18:21:59.007 回答
0

第一个声明:

template<unsigned int... Ns>
struct sum;

是前向声明:它将模板声明为具有可变数量unsigned int参数的模板。

第一个特化是元函数的基本情况,它适用于可变参数包只有一个参数的情况:

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++ 模板机制(如实例化、模板专业化等)的信息。

于 2013-09-07T18:24:25.010 回答
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
于 2020-10-29T02:07:48.007 回答