当调用时,为什么ranges ::累积的init as std :: Move(init)

Why does ranges::accumulate not pass init as std::move(init) when invoke?

本文关键字:init as std Move 调用 为什么 ranges      更新时间:2023-10-16

在2018年3月17日的commetulate.hpp

的提交d5e9afc起

通过一个范围时,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));

此代码试图避免假设C 17。 std::move -ing init可能会对其进行修改(这就是《移动语义》的目的,归根结底(。这给我们留下了这样的东西:

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

这将导致C 17之前的不确定行为。范围V3也将自己作为C 11和C 14的库。

相关文章: