Home > other >  How can I make a constructor create a different lambda each time when called?
How can I make a constructor create a different lambda each time when called?

Time:01-18

I have this simple code:

#include <iostream>
#include <functional>

class a {
public:
    a() {
        func = [] {
            static int i = 0;
            i  ;
            std::cout << i << std::endl;
        };
    }
    std::function<void()> func;
};

int main()
{
    a a1;
    a1.func();
    a a2;
    a2.func();
}

I expected an output like this:

1
1

But instead it was:

1
2

Then I checked the memory addresses of the lambdas in the two instances of a and they were the same. This means that the lambda is created once and then used in all instances. What I am looking for is to make the constructor create a different lambda every time when it gets called. I turned off the compiler optimizations but there was no effect.

INFO: I am using MSVC.

CodePudding user response:

Conceptually, you do have separate instances of the lambda. What you have witnessed might be a compiler optimization, but the actual issue is that static makes i owned by the function body itself, and thus shared by all instances of your lambda.

What you want instead is to make i a member of each lambda instance, which you can do with an extended capture list:

func = [i = 0]() mutable {
    i  ;
    std::cout << i << std::endl;
};

CodePudding user response:

If you are on a C 11 only compiler, you can drop the lambda syntax sugar and return to the function objects (which lambdas are a shorthand version of defining)

struct CallCounter
{
    int i = 0;
    void operator()()
    {
        i  ;
        std::cout << i << std::endl;
    }
};

class a {
public:
    std::function<void()> func = CallCounter{};
};

  • Related