折叠表达式扩展包中的最大元素数

时间:2019-06-02 00:34:16

标签: c++ c++17

请考虑以下程序:

#include <iostream>
#include <algorithm>

template<typename T, std::size_t N, std::size_t... I>
T sum_impl(T (&a)[N], std::index_sequence<I...>)
{
  return (a[I] + ...);
}

template<typename T, std::size_t N>
T sum(T (&a)[N])
{
  return sum_impl(a, std::make_index_sequence<N>{});
}

int main()
{
    int a[512] = {[0 ... 511] = 1};
    std::cout << "Sum =" << sum(a) << std::endl;
}

Demo

在上述情况下,fold表达式是恕我直言,是展开for循环的好方法。自然产生的问题是:

  1. 每个供应商的fold表达式的扩展包中是否存在最大数量的元素,以及我们如何获取/访问该数量(例如,出于某些原因在VC ++ 2017中,最大数量为745,否则程序不会不编译)?
  2. 折叠表达式的扩展包中是否有许多元素,如果超出这些元素,性能将会受到损害。也就是说,是否有一个经验法则,如果超过此数字,使用for循环会更好?

1 个答案:

答案 0 :(得分:3)

C ++规范中的fold表达式的规范如下:

  

8.1.6折叠表达式折叠.p折叠。      

fold表达式执行模板参数包的折叠   (17.5.3)通过二进制运算符...

它持续了两段。它们什么都没有设置C ++编译器必须支持的折叠表达式的最小或最大大小。在C ++标准的本部分中未指定;因此,这完全取决于单个C ++实现。没有确定特定编译器限制的指定方法。您发现您的特定编译器将fold表达式限制为745个值。限制的原因显然与编译器的内部实现细节有关。而且,如果不熟悉它们,就没有太多可说的了。其他编译器的限制可能更大或更小,或者仅受可用内存量的限制。

PS。关于模板参数包规范的引用,C ++标准的该部分没有指定C ++编译器必须支持的参数包的最小/最大大小。

编辑:有人指出,附件B列出了一些建议,但没有将它们指定为绝对要求;并且未明确调用折叠表达式的最大限制。

但是,附件B确实指出:

  

模板声明[1 024]中的模板参数。

有人可能会争辩说,如果这种“参数”的用法将参数包含在参数包中,则将间接影响折叠表达式。