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

Is function passed to std::for_each allowed to make copies of sequence elements?

本文关键字:许制作 元素 副本 是否 函数 std for each      更新时间:2023-10-16

我最近偶然发现了cpp首选项的措辞:

与其他算法不同,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());
 
// ...
}

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

[algorithms.parallel.exec]/3 说:

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

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

但是[alg.foreach]/9说for_each(ExecutionPolicy&&, ForwardIterator, ForwardIterator, Function)

实现没有根据 [algorithms.parallel.exec] 授予的自由,无法从输入序列中制作元素的任意副本。

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

所以这些都不适用于较旧的非并行for_each(InputIterator first, InputIterator last, Function f)。 对于该算法,情况很简单,由于效果被指定为"f应用于取消引用范围内每个迭代器的结果[first, last)...",因此函子参数必须是例如*first而不是*first的副本.

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

函数的签名应等效于以下内容:
void fun(const Type &a);
签名不需要包含 const &.

我认为您需要看到这样一个事实,即不允许for_each复制元素作为标准提供给用户的保证,而不是对应用于每个元素的用户谓词函数的限制。

相关文章: