我在这里写了一个答案:https://stackoverflow.com/a/44481507/2642059使用了accumulate
。
仿函数必须是二进制文件,其签名如下:Ret op(const auto& a, const auto& b)
但是:
签名不需要
const &
对二元仿函数的要求是:
不得使任何迭代器无效,包括结束迭代器,或修改所涉及范围的任何元素
当累积的对象本身就是一个容器时,我不清楚仿函数的要求。例如,允许这样的事情吗?
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;
});
是的,我知道这只是一个副本,我不是要求一个更好的解决方案,我问的是这个解决方案的有效性。
答案 0 :(得分:3)
我认为working draft比cppreference或其他更明确:
在
[first, last]
范围内,binary_op
既不会修改元素也不会使迭代器或子范围无效。
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
继续使用几个悬空指针。不好。