相关疑难解决方法(0)

lambda 表达式是合法的默认(非类型模板)参数吗?

以下所有标准参考均指N4861(2020 年 3 月布拉格后工作草案/C++20 DIS)


背景

在问答中 无捕获的 lambda 是结构类型吗?很明显,某些 lambda 表达式具有关联的闭包类型,这些闭包类型是(文字和)结构类型,因此特定的此类闭包类型可以用作非类型模板参数;本质上将结构类型 lambda 作为非类型模板参数传递。

template<auto v>
constexpr auto identity_v = v;

constexpr auto l1 = [](){};
constexpr auto l2 = identity_v<l1>;
Run Code Online (Sandbox Code Playgroud)

现在,根据[expr.prim.lambda.closure]/1 ,每个 lambda 表达式的类型都是唯一的

[...] 一个独特的、未命名的非联合类类型,称为闭包类型[...]

另一方面,[basic.def.odr]/1 [extract,强调我的]指出

任何翻译单元不得包含任何变量、函数、类类型、枚举类型、模板、参数的默认参数(对于给定范围内的函数)或默认模板参数的多个定义

可以说,默认模板参数被认为是需要尊重 ODR 的定义。

...这引出了我的问题:

  • lambda 表达式是否是合法的默认(非类型模板)参数,如果是,这是否意味着使用这种默认参数的每个实例化都会实例化一个独特的特化?

(如果接近非法,也请强调:例如,如果超出单个实例化的任何事情都会导致 ODR 违规)。


为什么?

如果这实际上是合法的,则每次调用带有 lambda 作为默认参数的变量模板都会导致唯一特化的实例化:

template<auto l = [](){}>
               // ^^^^^^ - lambda-expression as …
Run Code Online (Sandbox Code Playgroud)

c++ lambda templates language-lawyer c++20

33
推荐指数
1
解决办法
767
查看次数

标签 统计

c++ ×1

c++20 ×1

lambda ×1

language-lawyer ×1

templates ×1