是否允许在作为静态数据结构成员的lambda函数中捕获变量



我截取了以下代码。

bool parseTool() {
string name;
string version;
static /*!!*/ AttrMap attrMap = {
{"name", Attr([&](const string &val)->bool{name = val;return true;})},
{"version", Attr([&](const string &val)->bool{version = val;return true;})},
};
return parseAttributes(attrMap);
}

attrMap被声明为静态,lambda函数从parseTool的堆栈中捕获变量。

当编译开始产生垃圾时,编译不会产生错误,并且可执行文件运行得很愉快。当然,删除"static"可以修复"trash"问题(可能将名称和版本设置为static也会修复它,但我还没有尝试过(。我不明白在这种情况下,当静态attrMap初始化时,编译器会捕获什么。

问题是,编译器为什么不抱怨呢?标准中有什么东西可以标记这个案例吗(我找不到(?编译器在那里做什么?

我在linux上用-std=c++17运行gcc-7.2.8。

编译器无法知道您捕获的引用在下次调用lambda时将不再有效,甚至无法知道是否会再次调用lamda。

你发布的代码很危险,很可能会失败,但根据标准,它是完全有效的,所以编译器可以自由接受它,而不会发出警告。

若要修复它,请按值捕获变量或使lambda不是静态的。使lambda为静态可能没有多大意义,因为在大多数实现中创建lambda可能并不昂贵,并且取决于lambda的使用方式可能会完全内联。

最新更新