我想创建一个生成lambda的函数,其中每个lambda都有自己的静态变量。但是,与我的想法相反,静态变量似乎在实例之间共享。例如,
#include <iostream>
auto make_lambda(){
return [](){
static auto count = 0;
return count++;
};
}
int main() {
auto a = make_lambda();
auto b = make_lambda();
std::cout << &a << ", " << a() << std::endl;
std::cout << &b << ", " << b() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
退货
0x7ffc229178df, 0
0x7ffc229178de, 1
Run Code Online (Sandbox Code Playgroud)
因此a
,b
似乎是唯一的实例,但它们共享该静态计数。我以为我会看到并且确实希望看到类似
0x7ffc229178df, 0
0x7ffc229178de, 0
Run Code Online (Sandbox Code Playgroud)
确保每个lambda都有自己的静态变量的最简单方法是什么?
Que*_*tin 11
抛弃静态变量并使用扩展的lambda捕获:
#include <iostream>
auto make_lambda(){
return [count = 0]() mutable {
return count++;
};
}
Run Code Online (Sandbox Code Playgroud)
如果您希望不同的lambda实例与其各自的副本共享状态,而不是在它们之间共享状态,则可以std::shared_ptr
改用:
auto make_lambda(){
return [count = std::make_shared<int>(0)]() mutable {
return (*count)++;
};
}
Run Code Online (Sandbox Code Playgroud)
您可以利用以下事实:实例化函数以及它们所包围的模板化实体在函数中定义了自己的静态变量副本。正在make_lambda
变成范本...
template<int>
static auto make_lambda(){
return [](){
static auto count = 0;
return count++;
};
}
Run Code Online (Sandbox Code Playgroud)
...将为每个新的模板参数生成一个新的静态变量,该变量对于TU是唯一的(由于函数模板本身是static
):
auto a = make_lambda<0>();
auto b = make_lambda<1>();
std::cout << &a << ", " << a() << std::endl;
std::cout << &b << ", " << b() << std::endl;
Run Code Online (Sandbox Code Playgroud)
这不是您想要的语法,但是可以完成工作。如果您不介意涉及预处理器和潜在的编译器扩展,则可以使用帮助程序宏获取简单的函数调用语法。
#define make_lambda() make_lambda<__COUNTER__>()
Run Code Online (Sandbox Code Playgroud)
__COUNTER__
GCC扩展名在哪里,每次在任何单个TU中需要扩展时,它都会扩展到新的号码。