C++11 lambda as member variable?

Viewed 59937

Can lambda's be defined as class members?

For example, would it be possible to rewrite the code sample below using a lambda instead of a function object?

struct Foo {
    std::function<void()> bar;
};

The reason I wonder is because the following lambda's can be passed as arguments:

template<typename Lambda>
void call_lambda(Lambda lambda) // what is the exact type here?
{ 
    lambda();
}

int test_foo() {
    call_lambda([]() { std::cout << "lambda calling" << std::endl; });
}

I figured that if a lambda can be passed as a function argument then maybe they can also be stored as a member variable.

After more tinkering I found that this works (but it's kind of pointless):

auto say_hello = [](){ std::cout << "Hello"; };
struct Foo {
    typedef decltype(say_hello) Bar;
    Bar bar;
    Foo() : bar(say_hello) {}
};
6 Answers

As long as lambda is constant (without closures), you can do something like this:

#include <iostream>

template<auto function>
struct Foo
{
    decltype(function) bar = function;
};

void call_lambda(auto&& lambda)
{
    lambda();
}

int main()
{
    Foo<[](){ std::cout << "Hello"; }> foo;
    foo.bar();
    call_lambda(foo.bar);
}

https://godbolt.org/z/W5K1rexv3

Or we can apply deduction guides to make it work for all lambdas:

#include <iostream>

template<typename T>
struct Foo 
{
    T bar;
};

template<typename T>
Foo(T) -> Foo<std::decay_t<T>>;

void call_lambda(auto&& lambda)
{
    lambda();
}

int main()
{
    std::string hello = "Hello";
    Foo foo([&](){ std::cout << hello; });
    foo.bar();
    call_lambda(foo.bar);
}

https://godbolt.org/z/cenrzTbz4

Related