Bad things can and will happen.
struct my_functor { void operator()(int x) { sum += x; } int sum = 0; } std::vector<int> v{1,2,3}; const auto& s = my_for_each(v.begin(), v.end(), my_functor{}); auto sum = s.sum;
This code is undefined. You are creating a temporary instance of my_functor . This is associated with a rvalue reference, extending its lifetime until it receives a call to the my_for_each function. When the function exits, it will return the rvalue reference to a temporary one. However, when the function exits, the rvalue reference that is temporarily initially associated with it will be destroyed because it is local. At this point, the temporary part will be destroyed. The net effect of all this is that s is a link right away.
Note that with the original for_each functor would be returned with a value, and the link would for_each to it directly, extending its lifetime.
Herb Sutter talks about this in this cppcon talk: https://www.youtube.com/watch?v=hEx5DNLWGgA . Basically, when you return a link / pointer to a function, there are very few reliable options that it can actually reference. The arguments to the function, which are taken by reference, are one of them, but the arguments to the functions from const ref and rvalue ref are not related to the fact that they attract temporary ones and cause the function to return to hang. I wrote about this topic here: http://www.nirfriedman.com/2016/01/18/writing-good-cpp-by-default-in-the-stl/ .
If you want to take a functor and avoid building an object, I just take it by translating the link and I wonβt return anything. What for? Because, if subsequently the user does not need a functor, he can just pass the rvalue and not worry about using the return incorrectly. And if they need it, they can just build it, pass it as an lvalue, and then use it after.
template< class InputIt, class UnaryFunction > void my_for_each( InputIt first, InputIt last, UnaryFunction&& f); my_functor s{}; my_for_each(v.begin(), v.end(), s); auto sum = s.sum;
No construction / demolition, no problems. Although I would caution that if you try to avoid this for performance reasons, it is probably wrong if your functor / lambda is not big, which is unusual.