One of the methods of a class C
needs to return a struct
containing a pair of integers and a fresh instance of C
. It may look awkward, but given the overall design, this makes a lot of sense (think of a Waveform
class returning a range of itself as a copy, with the indication of where the range starts and ends).
The problem is that this doesn't seem to be allowed. I can redesign my class in order to circumvent this issue but can you explain me why, from the point of view of the compiler, this cannot be done
struct S {
struct S2 {
S s;
};
};
as S
is an incomplete type (this is the compiler error), and instead this is perfectly fine
struct C {
struct C1 {
C makeC() { return C(); }
};
};
Where is a substantial difference?
At the point where you attempt to define S::S2
, the type S
is still an incomplete type, since its definition hasn't been completed yet. And class data members must have a complete type.
You can easily fix it like this:
struct S
{
struct S2; // declare only, don't define
// ...
};
struct S::S2
{
S s; // now "S" is a complete type
};
It is essentially a design decision of C++ to not consider a type complete until the end of its definition. This prevents many pathological situations like the following example:
struct X
{
struct Y { X a; };
int b[sizeof(Y)]; // "sizeof" requires a complete type
};
When you want to define a class you need a full definition of all the embedded (non-reference and non-pointer) members. While defining a class the class is not fully defined. That is, within a class definition the class under definition is merely declared, not defined.
That said, you can still have a member of your class in a nested class. You just need to define the nested class after the outer class is defined:
struct S {
struct S2;
};
struct S::S2 {
S s;
};
Since S
is completely defined with the first closing braces, it can be used as embedded member after this point.
When you define a member function inside the class definition the definition is resolved as if it appears immediately after the class definition on the closest namespace level. That is, member function definitions know the fully defined class. The same doesn't apply to nested classes.
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