c++c++14std-functiongeneric-lambda

C++14: Generic lambda with generic std::function as class member


Consider this pseudo-snippet:

class SomeClass
{
public:
    SomeClass()
    {
        if(true)
        {
            fooCall = [](auto a){ cout << a.sayHello(); };
        }
        else
        {
            fooCall = [](auto b){ cout << b.sayHello(); };
        }
    }
private:
    template<typename T>
    std::function<void(T)> fooCall;
};

What I want is a class member fooCall which stores a generic lambda, which in turn is assigned in the constructor.

The compiler complains that fooCall cannot be a templated data member.

Is there any simple solution on how i can store generic lambdas in a class?


Solution

  • There is no way you'll be able to choose between two generic lambdas at run-time, as you don't have a concrete signature to type-erase.

    If you can make the decision at compile-time, you can templatize the class itself:

    template <typename F>
    class SomeClass
    {
    private:
        F fooCall;
    
    public:
        SomeClass(F&& f) : fooCall{std::move(f)} { }
    };
    

    You can then create an helper function to deduce F:

    auto makeSomeClassImpl(std::true_type) 
    {
        auto l = [](auto a){ cout << a.sayHello(); };
        return SomeClass<decltype(l)>{std::move(l)};
    }
    
    auto makeSomeClassImpl(std::false_type) 
    {
        auto l = [](auto b){ cout << b.sayHello(); };
        return SomeClass<decltype(l)>{std::move(l)};
    }
    
    template <bool B>
    auto makeSomeClass() 
    {
        return makeSomeClassImpl(std::bool_constant<B>{});
    }