C++: Force lamba instances to have unique static variables

Ditch the static variable and use an extended lambda capture:

#include <iostream>

auto make_lambda(){
    return [count = 0]() mutable {
        return count++;
    };
}

If you want different lambda instances to share state with their respective copies but not between them, you can use a std::shared_ptr instead:

auto make_lambda(){
    return [count = std::make_shared<int>(0)]() mutable {
        return (*count)++;
    };
}

You can leverage the fact that instantiated functions, and the templated entities they enclose, have their own copies of static variables defined in the function. Turning make_lambda into a template...

template<int>
static auto make_lambda(){
    return [](){
        static auto count = 0;
        return count++;
    };
}

... will generate a new static variable for each new template argument, unique to the TU (on account of the function template itself being static):

auto a = make_lambda<0>();
auto b = make_lambda<1>();
std::cout << &a << ", " << a() << std::endl;
std::cout << &b << ", " << b() << std::endl;

Which is not quite the syntax you wanted, but gets the job done. If you don't mind involving the preprocessor and potentially compiler extensions, you can get the simple function call syntax with a helper macro.

#define make_lambda() make_lambda<__COUNTER__>()

where __COUNTER__ is a GCC extension that expands to a new number every time expansion is required in any single TU.


You can pass a variable by value to the lambda. Moreover you have to make the lambda mutable so you'll be able to modify the value during execution. Normally labdas are like a const methods.

auto make_lambda(){
    int count = 0;
    return [count]() mutable {
        return count++;
    };
}

Tags:

C++

Lambda

C++14