标头中的内联和constexpr不捕获lambda有什么区别?

时间:2019-02-02 11:44:42

标签: c++ lambda c++17 inline constexpr

如果我在标头中声明了一个不可捕获的lambda,那么两者之间有什么区别

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

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

如果我理解正确,constexpr表示内联,而lambda默认为constexpr。因此,我什至不确定我是否需要inlineconstexpr关键字。

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

1 个答案:

答案 0 :(得分:4)

  

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

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

  

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

在我们的例子中,我们既没有函数也没有静态数据成员,因此它不是隐式内联的。您必须明确地将其标记为这样。

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

  

如果相应的 lambda-expression parameter-declaration-clause 后面跟着{{,则函数调用运算符或任何给定的运算符模板专长都是constexpr函数。 1}}或constexpr,或满足constexpr函数([dcl.constexpr])的要求。

呼叫操作符默认为consteval,而lambda 本身则不是。对于无需捕获的lambda基本上可以满足要求,您仍然可以使用call运算符-如本节示例所示:

constexpr

简而言之,如果您在标头中声明此lambda,则肯定需要使用auto ID = [](auto a) { return a; }; static_assert(ID(3) == 3); // OK 关键字,并且只要对inline关键字打一下就没有什么害处。