Почему диапазоны:: накапливать не передать init как std::move(init) при вызове?
По состоянию на коммит d5e9afc 17 марта 2010 года из накопления.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 должен быть переопределен каким-либо образом, верно? Так почему же не стоит разорвать его в первую очередь?
init = invoke(op, std::move(init), invoke(proj, *begin));
1 ответ
Этот фрагмент кода пытается избежать предположения, что C++17 может показаться. std::move
-ную init
потенциально может изменить его (для этого и нужна семантика перемещения в конце дня). И это оставляет нас с чем-то вроде этого:
init = /* An expression that maybe modifies init */;
Что приведет к неопределенному поведению до C++17. range-v3 также объявляет себя библиотекой для C++ 11 и C++14.