In other words, there is no need for the class c; in your 2nd code if there was already a typedef before it.
(But I see what you're saying, it's unfortunate that simply adding that line is harmful to the compilation.) |
This is essentially correct.
typedef a b;
creates a definition for b which is the same as a, which naturally includes an implied declaration of b as a type.
If, then,
class b;
is written, it is an attempt to create a declaration of type b, which as already been declared and defined with the previous typedef, creating a conflict (not an inconsistency).
In other words, it is similar to trying:
1 2 3 4 5 6 7 8
|
class A
{ int x;
};
class A
{ float y;
};
| |
Here, the second "class A" conflicts with the previous declaration/definition of class A. If permitted, the second would make the first disappear.
So, when a typedef creates a declaration/definition of a type, and then an attempt to declare a new type of the same name appears later, it is a similar conflict.
In part this means the compiler does consider a small distinction between the typedef which creates a declaration/definition of a type and a forward class declaration, because, as some reasoning I read long ago, it is all too easy to confuse the situation where, say, b (from above) is created and later a declaration which forward declares what the programmer may think is a new type 'b', when such a type has already been created.
When a typedef is created which transports a declaration over a namespace, this could be confusing:
1 2 3 4 5 6 7
|
namespace delme{
class c {int i,j,k;};
};
typedef delme::c c;
class delme::c;
class c;
| |
If allowed, the last two lines suggest the forward declaration of the exact same class, where the second was transported over the namespace via typedef.
The first one is allowed, as it is merely a forward declaration that matches.
The second isn't because the compiler "sees" 'c' differently, where the fact it is a typedef is incorporated in what it recognizes as the type of 'c'. It 'sees' 'c' as having the type "delme::c".