Isn't it better to pass function objects into the STL algorithms by forwarding reference rather then by value? It would allow one to utilize ref-qualifiers of operator () of function objects passed.
There are a couple of questions about std::for_each algorithm on SO (1, 2), which are considering a problem with changing of observable state of function object passed to std::for_each.
Passing functional objects by lvalue leference would solve the problem as a side effect even for those of algorithms, which can't return functional object (due to they should return, say, output iterator last value or something else).
For example the algorithm std::for_each can be changed from (copied from libc++):
template<typename _InputIterator, typename _Function> _Function for_each(_InputIterator __first, _InputIterator __last, _Function __f) { for (; __first != __last; ++__first) __f(*__first); return _GLIBCXX_MOVE(__f); } to:
template<typename _InputIterator, typename _Function> _Function && for_each(_InputIterator __first, _InputIterator __last, _Function && __f) { for (; __first != __last; ++__first) _GLIBCXX_FORWARD(_Function, __f)(*__first); return _GLIBCXX_FORWARD(_Function, __f); } or (if such breaking changing is allowed) std::for_each can return void without loss of functionality. Similar changes (change from passing by value to passing by forwarding reference and change all invocations to calling std::forwarded function object instead of just non-const-lvalue) are possible for all the rest <numeric>'s and <algorithm>'s algorithms.
I know a partial workaround: is to pass object, wrapped by std::ref (or std::cref to enforce const this), but there are issues with forwarding operator () cv-ref-qualifiers from wrapped functional object to wrapper's operator ().
Another workaround is to explicitly specify reference argument type into alorithm's template parameter list, but currently Function parameter sadly always follows the InputIterator and OutputIterator parameters in the list:
#include <iostream> #include <list> #include <algorithm> #include <iterator> #include <utility> #include <cstdlib> int main() { std::list< int > l{{1, 2, 3, 4}}; std::copy_n(std::cbegin(l), l.size(), std::ostream_iterator< int >(std::cout, " ")); std::cout << std::endl; struct F { int state; void operator () (int i) { state += i; } } f{0}; using I = std::list< int >::const_iterator; std::for_each< I, F && >(std::cbegin(l), std::cend(l), std::move(f)); std::cout << f.state << std::endl; return EXIT_SUCCESS; } By the way the change would allow to pass a non-copyable and/or non-moveable function objects to the algorithms w/o wrapping them.