[英]Do lambda expressions that appear in different definitions of a same entity produce the same closure type?
在 C++20 中,我们可以在未计算的上下文中使用 lambda 表达式。 考虑以下 C++20 代码:
foo.cpp文件
#include <typeinfo>
struct Foo {
using T = decltype([]{});
}; // struct Foo
const std::type_info& getType() { return typeid(typename Foo::T); }
主.cpp
#include <iostream>
#include <typeinfo>
struct Foo {
using T = decltype([]{});
}; // struct Foo
const std::type_info& getType();
const std::type_info& getTypeFromMain() { return typeid(typename Foo::T); }
int main() {
std::cout << std::boolalpha
<< (getType() == getTypeFromMain());
return 0;
}
标准C++下的程序output应该是什么?
据我所知,GCC 和 clang output false
。 他们认为所有 lambda 表达式都应该产生不同的闭包类型并且对翻译单元来说是“本地的”。
另一方面, [basic.def.odr] 13.10指出,不同翻译单元中同一实体的不同定义中相应的 lambda 表达式引入的闭包类型应该相同,程序应该 output true
。 GCC 和 clang 错了吗?
是的,闭包类型在所有翻译单元中都是相同的,编译器仍在追赶它。 这样做的机制是根据闭包类型在整体定义中的位置为闭包类型生成(损坏的)名称(如评论中所述,通过对它们进行计数)。 标准中这种方法起作用的原因有些微妙。
[basic.def.odr]/13.10 没有指定闭包类型相同; 它使用“应”,因此要求它们相同(如下所示,仅在更微妙的情况下才有效果)。 /14 具有这种效果:“行为就好像有一个具有单一定义的单一实体”,这必然会产生单一的闭包类型。 即便如此,说 lambda 表达式“产生相同的闭包类型”也是不恰当的:相反,只有一种产生的闭包类型与整个程序相关。
请注意,如果没有这样的规定,像这样的简单功能
#ifndef MY_HEADER_HH
#define MY_HEADER_HH
inline auto make_assign(int i) {return [i](int &x) {x=i;};}
#endif
如果多个翻译单元试图将各种make_assign(…)
对象添加到std::vector<decltype(make_assign(0))>
,则将不起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.