Мне интересно, почему функторы передаются копией в функции algorithm
:
template <typename T> struct summatory
{
summatory() : result(T()) {}
void operator()(const T& value)
{ result += value; std::cout << value << "; ";};
T result;
};
std::array<int, 10> a {{ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 }};
summatory<int> sum;
std::cout << "\nThe summation of: ";
std::for_each(a.begin(), a.end(), sum);
std::cout << "is: " << sum.result;
Я ожидал следующий вывод:
Суммирование: 1; 1; 2; 3; 5; 8; 13; 21; 34; 55; is: 143
Но sum.result
содержит 0
, то есть значение по умолчанию, назначенное в ctor. Единственный способ добиться желаемого поведения - захватить возвращаемое значение for_each
:
sum = std::for_each(a.begin(), a.end(), sum);
std::cout << "is: " << sum.result;
Это происходит потому, что функтор передается с помощью for_each
вместо ссылки:
template< class InputIt, class UnaryFunction >
UnaryFunction for_each( InputIt first, InputIt last, UnaryFunction f );
Таким образом, внешний функтор остается нетронутым, а внутренний (который является копией внешнего) обновляется и возвращается после выполнения алгоритма (живая демонстрация), поэтому результат будет скопирован (или перемещен) снова после выполнения всех операций.
Должна быть веская причина, чтобы сделать эту работу таким образом, но я действительно не понимаю обоснования в этом дизайне, поэтому мои вопросы:
- Почему предикаты алгоритмов последовательности-операций передаются копией вместо ссылки?
- Какие преимущества предлагает метод сквозной копии перед обратным ссылкой?