Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a std::function type or similar for lambda with auto parameter?

When I assign a lambda to an explicitly typed variable (for example when it is recursive, to capture the function in itself), I use std::function.

Consider this silly "bit counting" function as an example:

std::function<int(int)> f;
f = [&f](int x){ return x ? f(x/2)+1 : 0; };

What about the case when we use an auto parameter to generalize x, as introduced in C++14 generic lambda?

std::function<int(???)> f;
f = [&f](auto x){ return x ? f(x/2)+1 : 0; };

Obviously, I can't place auto in the function type parameters.

Is there a possibility to define a functor class generically enough to cover the exact case above, but still using lambda for the function definition?

(Don't over-generalize this, only accept a single auto parameter and hard-code the return value.) The use case would be for the scenario like above: capturing the function in itself by reference for recursive calls.

like image 216
leemes Avatar asked Jul 08 '15 06:07

leemes


People also ask

What is the type of lambda function in C++?

A lambda is an object (hence why we're referring to it as a functor, rather than a function) so has a type and can be stored. However, the type of the lambda is only known by the compiler (since it is compiler-generated), so you must use auto for declaration instances of the lambda.

How do you call a lambda function in C++?

Only variables that are mentioned in the lambda body are captured when a capture-default is used. To use lambda expressions in the body of a class member function, pass the this pointer to the capture clause to provide access to the member functions and data members of the enclosing class.

What is capture list in C++?

The capture list defines the outside variables that are accessible from within the lambda function body. The only capture defaults are. & (implicitly capture the used automatic variables by reference) and. = (implicitly capture the used automatic variables by copy).


1 Answers

You can create a lambda that calls itself by passing it to itself as a parameter:

auto f = [](auto self, auto x) -> int {
    return x ? self(self, x / 2) + 1 : 0;
};

std::cout << f(f, 10);

You can then capture that lambda in another lambda, so you don't have to worry about passing it to itself:

auto f2 = [&f](auto x) {
    return f(f, x);
};

std::cout << f2(10);
like image 103
Benjamin Lindley Avatar answered Sep 22 '22 13:09

Benjamin Lindley