c++ - accumulate 的 Functor 有什么要求?

标签 c++ language-lawyer functor accumulate binary-operators

我在这里写了一个答案: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/

相关文章:

c++ - 什么时候通过复制/引用?

c++ - 如果函数在匿名命名空间中声明,是否可以在全局命名空间中定义?

dictionary - 高效的 Redux reducers,避免不必要的对象复制

c++ - 当使用模板支持仿函数作为参数时,我应该使用什么限定符?

Haskell:类型 f a 实际上是什么意思?

c++ - 是否可以在 C++ 中将 std::map 与没有任何复制运算符的类一起使用?

c++ - 在不强制固定宽度的情况下删除 float 的科学记数法

c++ - throw 或 delete 表达式可以依赖吗?

c++ - 如何用 dll 和库打包 C++

c++ - 来自空括号的不明确复制分配的编译器差异