Search code examples
c++classlambdamember

Creating lambda expression in class using members


I am trying to create a class member function which returns a lambda expression, based on the class members. For simplification I created this example code.

#include <functional>

class A
{
private:
    int value;

public:
    // Default constructor
    A()
    : value(0)
    { };

    // Constructor
    A(int value)
    : value(value)
    { };

    // Returns a lambda expression
    std::function<int()> get_value()
    {
        return [](){ return value; };
        // Gives error: "error: 'this' was not captured for this lambda function"
    }
};

I know for this implementation it can be programmed much easier (leave away the lambda expression), but I think it is good to explain and understand the concept.

The question: how to use class member variables in class member lambda expressions? In other words: how do I capture 'this' within a lambda function in a class?


Solution

  • If you want to capture this then you should capture this:

    return [this](){ return value; };
    

    However, this comes with the usual caveat that the this captured by the lambda can only be used as long as this is alive.

    PS

    I know for this implementation it can be programmed much easier (leave away the lambda expression), [...]

    If you want to have a callable that returns you the value of an A then I wouldn't know how to do it (easily) without using a lambda expression. I rather see the problem in your design. As mentioned above the caller needs to be cautious to only use the returned std::function as long as the A object is alive. There is a non-obvious dependency with the effect that your A can be easily used wrong:

    auto f = A{}.get_value();
    

    This creates a broken std::function<int()>. Frankly, your code is what I would call "encapsulation gone terribly wrong". Of course your code is just an example, but consider this example:

    struct A { int value = 0; };
    
    int main() {
        A a;
        auto f = [&](){ return a.value; };
    }        
    

    Here the caller (ie the user of A) has the dependency (usability of f depends on lifetime of a) explicitly in their code.