header 中的内联和 constexpr 无捕获 lambda 有什么区别?

What is the difference between inline and constexpr captureless lambda in a header?

如果我在 header 中声明一个无捕获的 lambda,

之间有什么区别
inline auto myLambda = []() { ... };

constexpr auto myLambda = []() { ... };

如果我没理解错,constexpr 表示内联,lambda 表达式默认是 constexpr。所以我什至不确定我是否需要 inlineconstexpr 关键字。

我想通过声明 myLambda 内联来避免违反单一定义规则 (ODR),因为该变量在多个翻译单元中可见。

If I understand correctly, constexpr imply inline, and lambdas are constexpr by default.

第一部分是正确的,但不适用于这种情况。来自 [dcl.constexpr]/1:

A function or static data member declared with the constexpr or consteval specifier is implicitly an inline function or variable ([dcl.inline]).

在我们的例子中,我们既没有函数也没有静态数据成员,所以它不是隐式内联的。你必须明确地标记它。

第二部分不对。来自 [expr.prim.lambda.closure]/4:

The function call operator or any given operator template specialization is a constexpr function if either the corresponding lambda-expression's parameter-declaration-clause is followed by constexpr or consteval, or it satisfies the requirements for a constexpr function ([dcl.constexpr]).

调用运算符默认是constexpr,但lambda本身不是。对于 capture-less lambda 基本上没问题,您仍然可以使用调用运算符 - 如本节示例所示:

auto ID = [](auto a) { return a; };
static_assert(ID(3) == 3);                      // OK

简而言之,如果您在 header 中声明此 lambda,您肯定需要 inline 关键字,并且只需添加 constexpr 关键字也无妨任何一个。