以下所有标准参考均指N4861(2020 年 3 月布拉格后工作草案/C++20 DIS)。
在问答中 无捕获的 lambda 是结构类型吗?很明显,某些 lambda 表达式具有关联的闭包类型,这些闭包类型是(文字和)结构类型,因此特定的此类闭包类型可以用作非类型模板参数;本质上将结构类型 lambda 作为非类型模板参数传递。
Run Code Online (Sandbox Code Playgroud)template<auto v> constexpr auto identity_v = v; constexpr auto l1 = [](){}; constexpr auto l2 = identity_v<l1>;
现在,根据[expr.prim.lambda.closure]/1 ,每个 lambda 表达式的类型都是唯一的
[...] 一个独特的、未命名的非联合类类型,称为闭包类型[...]
另一方面,[basic.def.odr]/1 [extract,强调我的]指出
任何翻译单元不得包含任何变量、函数、类类型、枚举类型、模板、参数的默认参数(对于给定范围内的函数)或默认模板参数的多个定义。
可以说,默认模板参数被认为是需要尊重 ODR 的定义。
...这引出了我的问题:
(如果接近非法,也请强调:例如,如果超出单个实例化的任何事情都会导致 ODR 违规)。
如果这实际上是合法的,则每次调用带有 lambda 作为默认参数的变量模板都会导致唯一特化的实例化:
template<auto l = [](){}>
// ^^^^^^ - lambda-expression as …Run Code Online (Sandbox Code Playgroud)