Почему диапазоны :: накапливать не передают init как std :: move (init) при вызове? - PullRequest
0 голосов
/ 24 апреля 2018

По состоянию на коммит d5e9afc 17 марта 1998 года из аккумулят.hpp

При прохождении диапазона инициатор получает 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 перед вызовом call?

Этот инициал должен быть каким-либо образом переопределен, верно? Так почему же не стоит разорвать его?

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

1 Ответ

0 голосов
/ 24 апреля 2018

Этот фрагмент кода пытается избежать предположения, что C ++ 17 может показаться.std::move -ing init потенциально может изменить его (для этого и нужна семантика перемещения в конце дня).И это оставляет нам что-то вроде этого:

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

, что привело бы к неопределенному поведению до C ++ 17 .range-v3 также объявляет себя библиотекой для C ++ 11 и C ++ 14.

...