struct x
{
y *GetY(); //error: what is "y"?
struct y
{
};
};
Why does GetY have to be declared after struct y is declared? I thought order of class members in C++ did not matter? Does it have to do with the way parsing is done?
EDIT: It also doesn't work if I typename x::y *GetY();, which makes even less sense to me.
EDIT: It works if I forward declare, but this goes against everything I know about C++ classes...
How is it supposed to know what y is if it hasn't been declared yet?
And the order does matter, but it's probably too trivial to make a difference in most cases. Class members are constructed top to bottom, and that's also generally how they'll be laid out in memory.
You comparing apples to oranges which makes no logical sense. In the last example everything is declared within the struct but you are not making new types. In the first example you are nesting the definition of a completely new type within the first struct. In the last example, y is not a type. It is a variable of type int. In the first example y is a typename. Obviously a class function has to be able to access member functions and attributes that are declared within the same class otherwise the concept of classes would simply never work. Defining brand new type definitions is something completely different.
I'm not a compiler expert, but in hindsight it was a good question. At first glance, I was kind of surprised that the last example compiles. Most of the time the functions are defined in the .cpp so the declarations wouldn't have those kinds of dependencies. But considering that I always put attributes at the bottom and functions at the top, those inline functions with the decl/def simultaneously wouldn't work if the order of function/attribute declarations mattered. So it must be that the compiler processes type definitions in a different manner and requires at least a declaration prior to the first use of a type. You know how sometimes a function prototype can compile with a forward declaration ( class typename; ) instead of the header inclusion? Perhaps someone with compiler development experience can explain further.
Well, forward declaration is usually when you have some sort of circular dependency that can be solved by using a pointer somewhere. A pointer's size can be known without knowing anything about the type, so incomplete types are allowed to be pointers.
In this case I am actually using a pointer, so it can't be an issue of forward declaration. Of course, if I forward declare it then I can only use a pointer, but that's besides the point.
The point is, I'm pretty sure this doesn't have to do with what requires you to forward declare. If you have to forward declare functions in a namespace but not in a class, why do you have to forward declare a type in both cases?