2

Assume I have a class A say has 2 functions funn1 and func2.

When I write func1 first and inside func1 I have a lambda which needs to access A obj members, refer to local var and quite big.

const auto mylambda = [&, this](...) {}

Now I want to use the same lambda in func2. Wondering how to achieve it? Can I define the lambda in class header file?

Talenel
  • 422
  • 2
  • 6
  • 25
MingC
  • 83
  • 4
  • 7
    Why lambda rather than a member function ? – Eugene Sep 10 '21 at 02:03
  • If you want to use a lambda inside `func2` when that lambda captures references to local variables in `func1`, then you need to call `func2` from within `func1` and pass it a reference to the lambda – Kevin Sep 10 '21 at 02:07
  • 1
    Can you be more specific. Can you show what you've tried, and explain what undesirable or non-working results you are seeing. It's hard to understand what you're asking. Code speaks louder than words. – Sam Varshavchik Sep 10 '21 at 02:07
  • 4
    lambda is unnamed functor; For reuse and avoid code duplication, use a named functor, or a named function which create the lambda. – Jarod42 Sep 10 '21 at 07:51
  • when used the possible lamda in func2, of course it is supposed to access func2's local var (no more func1's local anymore). There are many ways to achieve the purpose as mentioned in above comments. But just to explore whether I could use lamda to achieve. I wrote my lamda in func1 first. later I realized I need its feature inside func2 also. – MingC Sep 11 '21 at 04:08

1 Answers1

0

Only non-static members have access to this. However, the problem is that you cannot declare a non-static lambda member variable, you can only declare static constexpr lambda members. In other words:

class Foo {
    auto lambda1 = [](){};                      // fails to compile
    static constexpr lambda2 = [](){};          // fine, but no access to this
    static constexpr lambda3 = [this](){};      // fails to compile
    static constexpr lambda4 = [](Foo* self){}; // works
};

However, what you can do is create non-static std::function member variable that captures this:

class Foo {
    std::function<void()> func = [this](){}; // works
};

The drawback is that this stores the pointer this in the func object, which seems a bit redundant, and also makes it problematic to move an object of type Foo (as that would invalidate the captured this pointer). Furthermore, you cannot capture a variable from another member function if the lambda is declared outside that member function.

But as already mentioned by others in the comments, do you even need a lambda at this point? You can just create an extra (private) member function instead of a lambda, and pass it references to any variables you want it to have access to.


I don't think this is what you meant, but you can of course pass a lambda from one member function to another:

class Foo {
public:
    void func1() {
        auto lambda = [&, this](){};
        func2(lambda);
    }

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

Be aware that whatever is captured by reference in func1() is only valid for the lifetime of the call to func1(). So this is invalid:

class Foo {
    std::function<void()> lambda;

public:
    void func1() {
        lambda = [&, this](){};
    }

    void func2() {
        lambda();
    }
};

Foo foo;
foo.func1();
foo.func2(); // undefined behavior
G. Sliepen
  • 7,637
  • 1
  • 15
  • 31