0

截至 2018 年 3 月 17 日的 d5e9afc 提交,accumulate.hpp

当传递一个范围时,init 会std::move像这样得到一次。

        T operator()(Rng && rng, T init, Op op = Op{}, P proj = P{}) const
        {
            return (*this)(begin(rng), end(rng), std::move(init), std::move(op),
                std::move(proj));
        }

然后上面的代码将调用它:

        T operator()(I begin, S end, T init, Op op = Op{}, P proj = P{}) const
        {
            for(; begin != end; ++begin)
                init = invoke(op, init, invoke(proj, *begin)); // why do we need this another copy of init?
            return init;
        }

我想知道为什么在调用调用之前我们需要另一个 init 副本?

这个初始化必须以任何方式覆盖,对吧?那么,为什么一开始就撕掉它是不好的呢?

                init = invoke(op, std::move(init), invoke(proj, *begin));
4

1 回答 1

3

这段代码试图避免假设它看起来是 C++17。std::move-inginit可能会修改它(这就是移动语义在一天结束时的用途)。这给我们留下了这样的东西:

init = /* An expression that maybe modifies init */;

这将导致C++17 之前的未定义行为。range-v3 也将自己宣传为 C++11 和 C++14 的库。

于 2018-04-24T11:13:46.783 回答