ODR与默认参数为Lambda的唯一类型的交互及跨TU安全性问题
关于Lambda作为默认模板参数的跨翻译单元类型一致性问题
首先看问题中的核心代码示例:
基础定义:每次默认实例化生成新类型
template <auto unique = [] {}> struct UniqueStruct {}; static_assert(!std::is_same_v<UniqueStruct<>, UniqueStruct<>>);
单个翻译单元(TU)内的一致性表现
using UniqueAlias = UniqueStruct<>; static_assert(std::is_same_v<UniqueAlias, UniqueAlias>); struct UniqueDerived : UniqueStruct<> {}; static_assert(std::is_same_v<UniqueDerived, UniqueDerived>);
问题解答
- 跨翻译单元的安全性:这种用法完全不安全,会导致类型不一致问题。
- 不同TU的Lambda类型差异:是的,不同TU中为
UniqueAlias/UniqueDerived生成的Lambda类型完全不同。根据C++标准,每个Lambda表达式的类型都是独一无二的,哪怕代码完全相同,位于不同TU中的Lambda也属于不同的实体,对应的类型不相等。这意味着TU1中的UniqueStruct<>和TU2中的UniqueStruct<>是两个完全不同的模板实例,它们的类型不相同。 - 多TU场景的适用性:
UniqueAlias和UniqueDerived确实不适用于多TU场景。只有当你显式为UniqueStruct指定一个跨TU可见且类型一致的模板实参(比如全局变量的地址、std::integral_constant枚举值等),此时UniqueStruct<X>在所有TU中才会被实例化为同一个类型,才能安全跨TU使用。
内容的提问来源于stack exchange,提问作者Joshua Maiche
相关产品推荐
相关产品推荐

