namespace O
{
class A{};
class A; // ok
typedef A K; // ok
struct A; // ok(C++11): A is a class but for references and pointer it have the same meaning
class K; // (1) error: K is a typedef (of a class...)
}
namespace U
{
typedef O::A A;
class A; // (2) error: A is a typedef (of a class...)
}
What is the reason(s) standard C++ don’t allow these cases (1 & 2) to compile?
You are confused or your example doesn’t show what you’re asking about. In your example code you are not trying to “forward declare a typedef” (such as thing isn’t possible or useful, see below) you are trying to redeclare an existing typedef-name (i.e. an alias for one type) as a completely different type.
You’ve already said
Kis a typedef forA, then you say it’s a classK. Make your mind up. It’s can’t be bothclass Aandclass K. Both (1) and (2) fail for that same reason.Going through these lines of the example:
Right so far.
I don’t know why you’ve said “C++11” here, this is OK in C++03 too. Classes and structs are the same kind of thing in C++. They are both “object types” and both “class types”. For a forward declaration the class-key (i.e.
structorclass) is interchangeable.Khas been declared as a typedef for classA, the name can’t be reused for declaring a new type in the same scope.[Aside: C does allow the following, because struct names and typedef names are in separate namespaces:
But now there are two different types called
struct KandK, which are unrelated. Doing this would be confusing and pretty dumb.]But from your comments maybe that’s not what you’re actually trying to do anyway.
Based on your comments maybe your broken examples are misleading and what you really want to do is:
This declares a typedef, for a type which is not defined yet.
It would be useless to forward-declare a typedef, you couldn’t do anything with it because you wouldn’t know what kind of type it was a typedef for, and there is very little you can do in C++ without knowing something about a type. Without knowing if it’s an object type, reference type or function type all you can realistically do is declare another typedef for it!
Consider:
I think you’re saying you want that to be valid, so do you expect this to work?
That should work, right? You don’t need to know the type of
Kbecause you only pass around pointers to it, right? Wrong. What if you later defineKlike this:Now
fhas the signatureint&* f()which is invalid. You have to know what a typedef is a typedef for, so its declaration has to say what it is not just forward-declare it as a name.