Does it make sense to use perfect forwarding in some STL algorithm ? What will be the deduced type ?
auto it = std::find_if(cont.cgebin(),
cont.cend(),
[](auto&& element){ return myFunction(std::forward<decltype(element)>(element)); })
I suppose the L-value version will be used (what about const ?), but what does determine that ? Is there other algorithms which would send a R-value ? I don't think so, because it would mean the predicate could be "consume" the element, whatever the result of the predicate.
The deduced type of element
depends on how the lambda is used within find_if
.
find_if
will never move by itself (you could pass a movable-iterator to find_if
, but then it's not find_if
that's doing the move, but the dereference operator on the iterator). find_if
will pass the value returned by the dereference operator to the lambda, so in your case it's most likely1 const T&
(it could well be T&
if you had a non-const container and used begin
/end
).
In both const T&
and T&
cases, std::forward
will do nothing, so you will just pass the parameter to myFunction
.
Note that the standard requires the predicate of std::find_if
to not modify its argument, so if you have myFunction(T&)
that modifies its argument, your code has undefined behavior.
You should not std::forward
here since there is no reason to accept an argument in find_if
using anything else than const T&
, so a better version would be2:
auto it = std::find_if(cont.cbegin(), cont.cend(),
[](const auto& element){ return myFunction(element); });
1 Some weird containers (std::vector<bool>
) will not return a const bool&
but a proxy-object, so your lambda needs to take a const auto&
or auto&&
, auto&
will be a compile-time error.
2 Some people (a lot?) uses auto&&
in these case, without the std::forward
of course, because it's shorter and gives you consistent lambda (you use auto&&
everywhere for the lambda).