Lambdas are for use with auto
or as a template parameter. You never know the type of lambda, and you cannot enter it. Each lambda has its own unique type. Even if you knew the type name, their type names usually contain a character that is not allowed for type names.
Why does lambda have its own type? because in fact the compiler creates a class defined this way:
struct /* unnamed */ {
This code is very close to equivalent (I skipped the conversion operator). As you can see, you are already using auto because lambdas prints the return type.
Some will say they use std::function<void(int*)>
, but I disagree. std::function
is a polymorphic wrapper around any callable. Since lambdas are callable types, they fit into it. In other words, it works like std::any
, but with a call statement. This will cause overhead in your application.
So what should you do?
use auto
! auto
not bad. In fact, it can even make your code faster and reduce unnecessary typing. If you feel uncomfortable with auto
, well, not worth it! auto
great, especially if you have no choice;)
In fact, you can avoid using auto
with the template parameter:
template<typename F, typename Arg> void parametric_print(F function, Arg&& arg) { function(std::forward<Arg>(arg)); }
Then use it as follows:
int main() { int a = 3; parametric_print([](int* a) {std::cout << *a << std::endl;}, &a); }
There you go, no auto
! However, the template parameter is displayed with the same rule as auto
. In fact, if the concept is accepted as standard, you can write the same function template as this:
// maybe C++20 void parametric_print(auto function, auto&& arg) { function(std::forward<decltype(arg)>(arg)); }
As Oktalist is mentioned, if concepts are accepted as standard, you can replace auto
with Callable
:
Callable print_int = [](int* a) { std::cout << *a << std::endl; };
But this does not lead to another type, it just applies some rules when deriving a type.