我在这里写了一个答案:https://stackoverflow.com/a/44481507/2642059使用 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]
。
另一方面,约束对于给定范围非常有意义,因为您使用几个迭代器定义它。
作为一个例子,想一想如果它们是 vector 的开始和结束迭代器会发生什么,在 vector 的末尾您决定将值推送到 binary_op
中。
一旦 vector 调整大小,accumulate
就会继续使用几个悬空指针。不好。
关于c++ - accumulate 的 Functor 有什么要求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44489824/