Is the above UnaryPredicate byte parameter?
Yes, this is what it says in the function parameter list. It takes the type of value displayed.
Also, lambda expressions are prvalues. Meaning, with C ++ 17 guaranteed copy elision that p initialized directly from the lambda expression. No additional copies of the closure or captured objects are made when passing it to a function (a function can make more copies inside, although this is not often).
If the predicate was passed by reference, the temporary object must be materialized. Thus, nothing is obtained for a lambda expression using the switch for passing by reference.
If you have other kinds of predicates that are expansive for copying, then you can pass std::reference_wrapper to this predicate object for a cheap descriptor. The wrapper operator() will do the right thing.
The definition is mostly historical, but currently it really is not a problem to do this with a transition by value.
To clarify why reference semantics would suck, try taking it over the years. A simple lvalue reference will not be executed, since now we do not support binding to rvalue. The link to the llue constant will also not be executed, since now we require that the predicate does not change any internal state, and why?
So, before C ++ 11 , we have no alternative. Passing by value will be better than a link. With the new standard, we can redefine our approach. To support rvalues, we can add rvalue reference overloading. But this exercise is in redundancy, because he does not need to do anything.
Passing the value, the caller has a choice in how to create it, and for prvalues, in C ++ 17 , it's practically free. If the calling user so desires, they can provide referential semantics explicitly. Therefore, nothing is lost, and I think a lot is achieved in terms of ease of use and design of the API.