The following code compiles fine:
#include <cstddef>
struct A {
char a;
static constexpr int off(void) { return offsetof(A, a); }
static constexpr int (*off_p)(void) = off;
};
The following seemingly similar code that just uses lambda for short, doesn't compile:
#include <cstddef>
struct A {
char a;
static constexpr int (*off_p)(void) =
[](void) static constexpr ->int { return offsetof(A, a); };
};
$ g++ -std=c++23 bad.cpp
In file included from /usr/include/c++/13/cstddef:50,
from bad.cpp:1:
bad.cpp: In static member function ‘A::<lambda()> static’:
bad.cpp:5:74: error: invalid use of incomplete type ‘struct A’
So basically I have 2 separate questions, since I don't understand what's going on here.
- Why in the first case the use of incomplete type is allowed?
- Why in the second case the use of incomplete type is NOT allowed?
constexpr
context? A lambda is not a function, it is a class type. The compiler has to create an object instance of the lambda, and then invoke a conversion operator on it to obtain a function pointer from it. – Cosmoramastatic
keyword inside your lambda upsets my compiler (MSVC) but, without that, I get the same error that you report. Is that use ofstatic
a g++ thing? – Vanscoyoffsetof
uses areinterpret_cast
, which can screw upconstexpr
stuff. – Vanscoysizeof(A)
instead of offsetof. – WeidmanA
. – TridentA
, then, just as with member function moved outside ofA
, it should seeA
as a complete type? – Weidmanstatic
be defined where I write it, i.e. directly in a class? For example static data members are AFAIK also moved outside of a class def, no? I don't think something that isstatic
can be created (and allocate some space?) directly when I write it, i.e. in this class. – Weidmanstatic
. With a normal class it would look like this: godbolt.org/z/drvj3fhv1 – Tridentstatic
applies to. – Tridentstatic
applies to since you wondered about it. Just disregard my example and focus on "Yes, the call operator isstatic
" - as in, the lambda's call operator. – Tridentstatic
applies only tooperator()
and therefore is irrelevant to whether or not this is a point of "complete-class context" or not. Thanks for that detail. – Weidman