Reputation: 60361
The following code does not compile:
struct object
{
static constexpr auto f;
};
constexpr auto object::f = [](auto&& x){x += 1;};
neither this one:
struct object
{
static constexpr auto f = [](auto&& x){x += 1;};
};
but this does (when f
is not a member):
static constexpr auto f = [](auto&& x){x += 1;};
Is there a way to declare and define a static constexpr data member lambda in C++14?
Upvotes: 3
Views: 1045
Reputation: 302758
The rule on static data members is in [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). Astatic
data member of literal type can be declared in the class definition with theconstexpr
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.
Only static const
integral/enumeration types or constexpr
members can be defined within the class definition. C++14 disallowed constexpr
lambdas period. The wording in [expr.const] used to read:
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);
— [...]
So in C++14, you just can't have a static lambda data member - you can't define it inline and you can't define it out of line because you have no way of declaring it (variables declared with auto
require an initializer). You're out of luck.
In C++17, we can have constexpr
lambdas thanks to p0170, at which point your second option is fine:
struct object
{
static constexpr auto f = [](auto&& x){x += 1;};
};
Upvotes: 4