【问题标题】:recursion when packed variadic template has zero elements打包可变参数模板具有零元素时的递归
【发布时间】:2018-10-22 02:41:45
【问题描述】:

我有这样的课:

template<std::size_t T, std::size_t... Args>
class A{
   public:
      std::array<int,summation<Args...>::value> x;
}

其中summation 定义为:

template<std::size_t size, std::size_t... sizes>
    struct summation
    {
        static const std::size_t value = size + summation<sizes...>::value;
    };


template<std::size_t size>
    struct summation<size>
    {
        static const std::size_t value = size;
    };

问题是当 Args 为空时(即我只指定 T 模板),基本情况不起作用,我收到一条编译错误消息:

error: wrong number of template arguments (0, should be 1 or more)

如何修改summation 的递归以正确处理sizeof...(Args)==0 时的情况并在这种情况下为求和返回值0?我正在使用 C++11。谢谢

注意:我还希望它可以在多线程环境中工作,在该环境中,可以由具有不同参数的不同线程同时调用求和。要在多线程环境中工作,需要进行哪些更改?谢谢

【问题讨论】:

  • 你标记了C++11,所以我猜你不能使用C++17,但是模板求和是新C++17模板折叠的典型作品
  • 在 C++17 中,它将是 (Args + ...)

标签: c++ c++11 variadic-templates


【解决方案1】:

声明应该是最通用的,然后您可以部分专门化可能的情况。以下解决方案有效:https://godbolt.org/z/Ye7xEJ

template<std::size_t... sizes>
    struct summation;

template<std::size_t size, std::size_t... sizes>
    struct summation<size, sizes...>
    {
        static const std::size_t value = size + summation<sizes...>::value;
    };

template<>
struct summation<> {
    static const std::size_t value = 0;
};

std::size_t foo() {
    return summation<1,3,4>::value;
}

std::size_t foo2() {
    return summation<>::value;
}

【讨论】:

  • 谢谢。我不明白为什么需要声明。如果没有声明(前 2 行),我会收到编译错误:“summation is not a class template struct summation
  • 作品但是...添加具有零尺寸的专业化,只有一种尺寸的专业化变得多余:您可以删除它,他的作品是由一种或多种尺寸的专业化制作的。另一个建议:问题标记为 C++11,因此您可以定义 constexpr,而不是简单地定义成本,values
  • @astrophobia - 是必需的,因为您最初定义了一个具有一种或多种尺寸的summation,并且主版本管理更多的情况,而专业化管理唯一的情况。现在,在 Balki 的解决方案中,summation 管理零个或多个大小(因为您要求零大小写);因此,一个或多个不再是主要案例(无法管理零案例),Balki 所写的是一种专业化。现在你有三个专业化(一个或多个,正好一个和正好零大小)但没有定义。前两行现在是定义(没有实现)。
  • @max66 谢谢。更新。是的,一种尺寸变得多余。
  • 但是,如果代码是多线程的并且我们试图并行计算多个总和怎么办?这还能用吗?我注意到这个解决方案中使用了许多静态变量
【解决方案2】:

这段代码:

size + summation<sizes...>::value;

翻译

summation<1,2,3,4>::value

进入

1 + summation<2, 3, 4>::value;  // Trims out first parameter; matches variadic version

2 + summation<3, 4>::value;    // Again, trims out first parameter;matches variadic version

3 + summation<4>::value;  // Matches <size> version. You support signature up-to this point

4 + summation<>::value;   // summation<> definition is missing in your code!!

这里有更详细的解释。 https://stackoverflow.com/a/48003232/1465553

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 2012-05-17
    • 1970-01-01
    • 1970-01-01
    • 2014-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多