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。所以我什至不确定我是否需要 inline
或 constexpr
关键字。
我想通过声明 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
关键字也无妨任何一个。
如果我在 header 中声明一个无捕获的 lambda,
之间有什么区别inline auto myLambda = []() { ... };
和
constexpr auto myLambda = []() { ... };
如果我没理解错,constexpr
表示内联,lambda 表达式默认是 constexpr。所以我什至不确定我是否需要 inline
或 constexpr
关键字。
我想通过声明 myLambda
内联来避免违反单一定义规则 (ODR),因为该变量在多个翻译单元中可见。
If I understand correctly,
constexpr
imply inline, and lambdas areconstexpr
by default.
第一部分是正确的,但不适用于这种情况。来自 [dcl.constexpr]/1:
A function or static data member declared with the
constexpr
orconsteval
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
orconsteval
, 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
关键字也无妨任何一个。