静态(可能是 constexpr)数据成员 l​​ambda

Static (possibly constexpr) data member lambda

以下代码无法编译:

struct object 
{
    static constexpr auto f;
};

constexpr auto object::f = [](auto&& x){x += 1;};

这一个都不是:

struct object 
{
    static constexpr auto f = [](auto&& x){x += 1;};
};

但这确实如此(当 f 不是会员时):

static constexpr auto f = [](auto&& x){x += 1;};

有没有办法在 C++14 中声明和定义静态 constexpr 数据成员 l​​ambda?

关于静态数据成员的规则在[class.static.data]:

If a non-volatile const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression (5.19). A static data member of literal type can be declared in the class definition with the constexpr specifier; if so, its declaration shall specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression.

只能在 class 定义中定义 static const integral/enumeration 类型或 constexpr 成员。 C++14 不允许 constexpr lambdas 句点。 [expr.const] 中的措辞曾经改为:

A conditional-expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine (1.9), would evaluate one of the following expressions:
— [...]
— a lambda-expression (5.1.2);
— [...]

所以在 C++14 中,你不能拥有静态 lambda 数据成员——你不能内联定义它,也不能外联定义它,因为你无法声明它 (用 auto 声明的变量需要初始化程序)。你真倒霉。


在 C++17 中,由于 p0170,我们可以使用 constexpr lambda,此时您的第二个选项很好:

struct object 
{
    static constexpr auto f = [](auto&& x){x += 1;};
};