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
就会继续使用几个悬空指针。不好。
我在这里写了一个答案: 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
就会继续使用几个悬空指针。不好。