Please educate me. Why does this compile:
struct compiles
{
struct A;
struct B
{
B(const A &a) : member(a.member) { }
int member;
};
struct A
{
A(const B &b) : member(b.member) { }
int member;
};
};
while this does not:
namespace doesnt
{
struct A;
struct B
{
B(const A &a) : member(a.member) { }
int member;
};
struct A
{
A(const B &b) : member(b.member) { }
int member;
};
}
(in MSVC 9.0)
The body of a class
/struct
/union
definition is processed all at once, allowing references to members of classes defined later. A namespace
is processed from top to bottom, and a forward declaration of struct A
does not allow you to use its members without a definition. Try moving the definition of B
's constructor out-of-class so you can put it after the definition of A
.
In C++, class scope is special. Any declaration that extends to or past then end of the class definition is automatically extended to the regions defined by its member definitions (3.3.6 [basic.scope.class]).
This means that in the first case both the first declaration of struct A
and the full definition of struct A
are visible in the body of B
and its constructor.
This doesn't apply to namespace scope so in the second case a.member
in the constructor of B
is an error because a definition of struct A
isn't yet visible.
[Also tested with g++ 4.2] The first one compiles because the compiler fully picks up all the types defined within the struct before actually compiling the nested structures (think about public inline methods using private attributes that appear later within the class). Within the namespace the compiler simply works top-to-bottom and doesn't have special rules.
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