If I declare a captureless lambda in a header, what is the difference between
inline auto myLambda = []() { ... };
and
constexpr auto myLambda = []() { ... };
If I understand correctly, constexpr
imply inline, and lambdas are constexpr by default. So I'm not even sure that I need the inline
or constexpr
keyword.
What I want to avoid by declaring myLambda
inline is One Definition Rule (ODR) violations, since this variable with be visible in multiple translation units.
If I understand correctly,
constexpr
imply inline, and lambdas areconstexpr
by default.
The first part is true, but not for this case. From [dcl.constexpr]/1:
A function or static data member declared with the
constexpr
orconsteval
specifier is implicitly an inline function or variable ([dcl.inline]).
In our case, we don't have either a function or a static data member, so it's not implicitly inline. You'd have to explicitly mark it as such.
The second part isn't quite right. From [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
orconsteval
, or it satisfies the requirements for a constexpr function ([dcl.constexpr]).
The call operator is constexpr
by default, but the lambda itself is not. Which for a capture-less lambda is basically fine, you can still use the call operator - as demonstrated in the example for this section:
auto ID = [](auto a) { return a; }; static_assert(ID(3) == 3); // OK
In short, if you're declaring this lambda in the header, you definitely need the inline
keyword and it doesn't hurt to just slap on the constexpr
keyword either.