Search code examples
c++c++11lambdastd-function

C++11 lambda as data member?


Can lambdas be defined as data 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 lambdas 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've figured that if a lambda can be passed as a function argument, then maybe they can also be stored as a data member.

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

auto say_hello = [] { std::cout << "Hello"; };

struct Foo {
    using Bar = decltype(say_hello);
    Bar bar;
    Foo() : bar(say_hello) {}
};

Solution

  • Templates make it possible without type erasure, but that's it:

    template<typename T>
    struct foo {
        T t;
    };
    
    template<typename T>
    foo<typename std::decay<T>::type>
    make_foo(T&& t)
    {
        return { std::forward<T>(t) };
    }
    
    // ...
    auto f = make_foo([] { return 42; });
    

    Repeating the arguments that everyone has already exposed: []{} is not a type, so you can't use it as e.g. a template parameter like you're trying. Using decltype is also iffy because every instance of a lambda expression is a notation for a separate closure object with a unique type. (e.g. the type of f above is not foo<decltype([] { return 42; })>.)