I tried to do something similar today. I was surprised it didn't compile.
struct Test {
// v----- Remove me to compile
// /*
static constexpr auto get_test1 = [](Test const& self) {
return self.test; // error, Test is incomplete
};
// */
// Handwritten version of the lambda
struct {
constexpr auto operator() (Test const& self) const {
return self.test; // ok
}
}
static constexpr get_test2{};
int test;
};
Live example
It says that the Test
type is incomplete in the scope. Yet the handwritten version of the lambda does indeed work. What is the technical reason for that? Is it an oversight in the standard, or is there a specific wording that makes Test
incomplete in the lambda?
This is what I could find:
§5.1.2 Lambda expressions [expr.prim.lambda]
[...] [ Note: Names referenced in the lambda-declarator are looked up in the context in which the lambda-expression appears. —end note ]
The lambda-expression’s compound-statement yields the function-body (8.4) of the function call operator, but for purposes of name lookup (3.4), [...] the compound-statement is considered in the context of the lambda-expression.
If I am not misreading the standard this means that Test
and self
both in the parameter as well in the body are looked/considered in the context of the lambda, which is the class scope in which Test
is incomplete.
As for why it is allowed with the nested class:
§9.2 Class members [class.mem]
- A class is considered a completely-defined object type (3.9) (or complete type) at the closing } of the classspecifier . Within the class member-specification, the class is regarded as complete within function bodies, default arguments, using-declarations introducing inheriting constructors (12.9), exception-specification s, and brace-or-equal-initializer s for non-static data members (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With