C++20跨翻译单元同一实体的Lambda闭包类型是否应一致?
问题分析与结论
按照C++20标准,该程序应输出true,GCC与Clang当前输出false的行为不符合标准要求。
代码回顾
foo.cpp
#include <typeinfo> struct Foo { using T = decltype([]{}); }; // struct Foo const std::type_info& getType() { return typeid(typename Foo::T); }
main.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++20标准的[basic.def.odr](13.10)条款明确规定:当同一实体在不同翻译单元中有多个定义时,这些定义中对应位置的lambda表达式必须引入相同的闭包类型。
在这个例子中,两个翻译单元中的struct Foo属于同一ODR匹配实体(定义完全一致),其内部using T = decltype([]{})中的lambda是对应位置的相同lambda表达式,因此它们的闭包类型必须被视为同一类型。typeid比较的结果自然应该是true。
编译器行为的问题
GCC和Clang当前的实现将每个lambda(即使是完全相同、出现在同一实体不同定义中的lambda)都生成唯一的、翻译单元局部的闭包类型,这直接违反了ODR中关于对应lambda闭包类型一致性的要求,属于不符合标准的行为。
内容的提问来源于stack exchange,提问作者Lancern
相关产品推荐
相关产品推荐

