内联和constexpr在标头中无捕获lambda有什么区别

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

本文关键字:lambda 区别 什么 constexpr      更新时间:2023-10-16

如果我在头中声明一个无捕获的lambda,之间的区别是什么

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

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

如果我理解正确的话,constexpr表示内联,默认情况下lambdas是constexpr。所以我甚至不确定我是否需要inlineconstexpr关键字。

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

如果我理解正确,constexpr表示内联,默认情况下lambda是constexpr

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

constexprconsteval说明符声明的函数或静态数据成员隐含地是内联函数或变量([dcl.inline])。

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

第二部分并不完全正确。来自[expr.prim.lambda.colose]/4:

如果相应的lambda表达式参数声明子句后面跟有constexprconsteval,或者它满足constexpr函数([dcl.constexpr])的要求,则函数调用运算符或任何给定的运算符模板专用化都是constexpr功能。

默认情况下,调用运算符constexpr,但lambda本身不是。对于一个无捕获的lambda基本上是可以的,您仍然可以使用调用运算符-如本节的示例所示:

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

简而言之,如果您在标头中声明这个lambda,那么您肯定需要inline关键字,而且只使用constexpr关键字也没有坏处。