accumulate 的 Functor 有什么要求?

What are the Requirements on accumulate's Functor?

我在这里写了一个答案: which uses accumulate

仿函数必须是二进制的,签名如下:Ret op(const auto& a, const auto& b) 但是:

The signature does not need to have const &

对二元函子的要求是:

Must not invalidate any iterators, including the end iterators, or modify any elements of the range involved

当积累到的对象本身就是容器时,我不清楚对函子的要求。例如,允许这样的事情吗?

const auto range = { 0, 1, 2, 3 };
const auto Ret = accumulate(cbegin(range), cend(range), vector<int>(), [](auto& a, const auto& b){
    a.push_back(b);
    return a;
});

是的,我知道这只是一个副本,我不是在寻求更好的解决方案我是在询问这个解决方案的有效性。

我认为 working draft 比 cppreference 或其他更明确:

In the range [first, last]binary_­op shall neither modify elements nor invalidate iterators or subranges.

其中 accumulate 声明为:

template <class InputIterator, class T>
T accumulate(InputIterator first, InputIterator last, T init);

template <class InputIterator, class T, class BinaryOperation>
T accumulate(InputIterator first, InputIterator last, T init, BinaryOperation binary_op);

因此我会说你的例子是有效的,因为你没有影响范围 [first, last]

另一方面,约束对于给定范围非常有意义,因为您使用几个迭代器定义它。
作为一个例子,想一想如果它们是向量的开始和结束迭代器会发生什么,在向量的末尾您决定将值推入 binary_op.
一旦矢量调整大小,accumulate 就会继续使用几个悬空指针。不好。