In discussion we had here I was playing around with passing functors. C++ STL passes functors as values (seen in std::for_each
, std::find_if
, std::transform
)
So declaring mine would be like this.
template<typename F>
void call_me(F f)
{
f();
}
Now, calling call_me(ftor{})
could probably invoke ftor
's copy constructor (it will most likely be copy elided, so not the case). But ftor f{}; call_me(f);
will result in copying. If ftor
has large data, it might be an issue.
We'll improve it by passing it as const reference (void call_me(const F& f)
) to get rid of unneeded copy. This is fine as long as ftor::operator()
is const
. If it is not, the call to call_me
would result in compilation error (losing const
qualifiers).
So, why to bother with const reference, use just reference (void call_me(F& f)
). This is fine, but it would not work for first case being call_me(ftor{})
since binsing r-value to (non-const) l-value reference is not valid.
Declaring f
as forwarding reference (void call_me(F&& f)
) seems to work in all cases. I believe, that this works thanks to reference collapsing.
So, why are templated functors not passed as forwarding references in functions from STL?