Каковы требования к накопителю?

Я написал ответ здесь: https://stackoverflow.com/a/44481507/2642059 который использует accumulate.

Функтор должен быть двоичным с такой сигнатурой: Ret op(const auto& a, const auto& b) но:

Подпись не должна иметь const &

Требование к бинарному функтору заключается в том, что он:

Не должен лишать законной силы любые итераторы, включая конечные итераторы, или изменять любые элементы участвующего диапазона

Когда объект, накопленный в себе, сам является контейнером, мне неясно, каковы требования к функтору. Например, разрешено ли что-то подобное?

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;
});

Да, я признаю, что это всего лишь копия, я не прошу лучшего решения, я спрашиваю о действительности этого решения.

4

Решение

я думаю рабочий проект является более явным, чем cppreference или чем-то еще:

В диапазоне [first, last]binary_­op не должен ни изменять элементы, ни делать недействительными итераторы или поддиапазоны.

куда 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],

С другой стороны, ограничение имеет смысл для данного диапазона, поскольку вы определяете его с помощью пары итераторов.
В качестве примера подумайте о том, что произошло бы, если бы они были начальными и конечными итераторами вектора, в конце которого вы решили выдвинуть значения в пределах binary_op,
Как только размер вектора изменится, accumulate продолжает работать с парой свисающих указателей. Не хорошо.

3

Другие решения

Других решений пока нет …