One of my pet peeves with teaching FP in C++ is that if we want to have efficient code, we need to catch functions and other callable objects as template arguments.
Because of this, we do not have function signatures that are self-documenting. Consider a function that outputs items that satisfy a predicate to the standard output:
We see that the template parameter is named
so we can imply that it needs to return a
bool (or something convertible to
and we can deduce from the function name
and the type of the first argument
that it should be a function that takes an
This is a lot of reasoning just to be able to tell what we can pass to the function.
For this reason,
std::function in his blog posts
it tells us exactly which functions we can pass in.
std::function is slow.
So, we either need to have a bad API or a slow API.
With concepts, the things will change.
We will be able to define a really short (and a bit dirty) concept that will check whether the functions we get are of the right signature:
Edit: Changed the concept name to Callable to fit the naming in the standard
[func.def] since it supports any callable, not just function objects
We will be able to call
foo with any callable that looks like a int-to-int function.
And we will get an error ‘constraint Callable<int(int)> is not satisfied’
for those that do not have the matching signature.
An alternative approach is to use
std::is_invocable type trait
(thanks Agustín Bergé for writing the original proposal and pointing me to it).
It will provide us with a cleaner definition for the concept,
though the usage syntax will have to be a bit different
if we want to keep the concept definition short and succulent.
When we get concepts (C++20, hopefully), we will have the best of both worlds – we will have an optimal way to accept callable objects as function arguments, and not sacrificing the API to do it.
Today, Functional Programming in C++ is again the Deal of the Day – you get half off if you use the code dotd032317au at cukic.co/to/manning-dotd