传递给std :: for_each的函数是否允许复制序列元素?

时间:2017-10-05 21:34:34

标签: c++ language-lawyer

我最近偶然发现cppreference的这句话:

  

与其他算法不同,for_each不允许复制序列中的元素,即使它们可以轻易复制。

声明是否正确?我没有在标准中找到任何理由。我能理解得很清楚吗?暗示同一页面中的以下示例无效?

struct Sum
{
    Sum(): sum{0} { }
    void operator()(int n) { sum += n; }
    int sum;
};

int main()
{
    std::vector<int> nums{3, 4, 2, 8, 15, 267};
 
    // ...
 
    // calls Sum::operator() for each number
    Sum s = std::for_each(nums.begin(), nums.end(), Sum());
 
    // ...
}

2 个答案:

答案 0 :(得分:3)

cppreference.com上的那句话来自于C ++ 17中关于并行算法新支持的措辞。

[algorithms.parallel.exec]/3说:

  

除非另有说明,否则实现可以从Tis_trivially_copy_constructible_v<T>为真的序列中生成元素的任意副本(类型为is_­trivially_­destructible_­v<T>)。

请注意,这是在讨论并行算法的上下文中,并行算法定义为标准库函数模板,其模板参数名为ExecutionPolicy

然后[alg.foreach]/9for_each(ExecutionPolicy&&, ForwardIterator, ForwardIterator, Function)

  

实现没有[algorithms.parallel.exec]授予的自由来从输入序列中创建元素的任意副本。

据推测,通过复制元素,一些并行化技术可以更加有效地处理普通类型。 (也许是为了让它们在记忆中连续?我只是在猜测。)

因此,这些都不适用于较旧的非并行for_each(InputIterator first, InputIterator last, Function f)。对于该算法,只是因为effects被指定为&#34;将f应用于取消引用[first, last)范围内的每个迭代器的结果。 。&#34;,仿函数参数必须是例如*first而不是*first的副本。

答案 1 :(得分:0)

措辞确实令人困惑,因为还提到了

  

该功能的签名应与以下内容相同:
  void fun(const Type&amp; a);
  签名不需要const&amp;。

我认为您需要看到for_each不允许将元素的副本作为标准给用户的保证,而不是对应用于每个元素的用户谓词函数的限制。 。