tags:

views:

411

answers:

4
class Namespace::Class;

Why do I have to do this?:

namespace Namespace {
    class Class;
}

Using VC++ 8.0, the compiler issues:

error C2653: 'Namespace' : is not a class or namespace name

I assume that the problem here is that the compiler cannot tell whether Namespace is a class or a namespace? But why does this matter since it's just a forward declaration?

Is there another way to forward-declare a class defined in some namespace? The syntax above feels like I'm "reopening" the namespace and extending its definition. What if Class were not actually defined in Namespace? Would this result in an error at some point?

+2  A: 

That is just how the C++ standard is written.

Daniel A. White
His answer might not be the most polite, but is plain correct. It's just that the standard says that the way you want to forward declare the classes is not permitted. Simple as that
Edison Gustavo Muenz
"Because the standard says so" is often a very good answer. It is usually improved by intelligent speculation on why the standard says so, but in a case like this (where you're complaining about the notation used) the speculation is probably superfluous.
David Thornley
@STingRaySC: On the contrary, sometimes it is very important to know what the rules are, and less important to know why. For example, it's very important that all drivers in the US drive on the right, and unimportant why we settled on the right side. Notational issues in languages are often like this.
David Thornley
+10  A: 

Because you can't. In C++ language fully-qualified names are only used to refer to existing (i.e. previously declared) entities. They can't be used to declare new entities.

And you are in fact "reopening" the namespace to declare new entities. If the class Class is later defined as a member of different namespace - it is a completely different class that has nothing to do with the one you declared here.

Once you get to the point of defining the pre-declared class, you don't need to "reopen" the namespace again. You can define it in the global namespace (or any namespace enclosing your Namespace) as

class Namespace::Class {
  /* whatever */
};
AndreyT
@STingRaySC: The only way to forward-declare a nested class is to put the declaration inside the *definition* of the enclosing class. And there's indeed no way to forward-declare the nested class before the definition of the enclosing class.
AndreyT
@STingRaySC: A nested class can be fwd declared -- see my answer.
John Dibling
@John Dibling: *Nested class* is a class declared inside another class. A class declared immediately inside a namespace is not a nested class. There's nothing about sensted classes in your answer.
AndreyT
+2  A: 

You're getting correct answers, let me just try re-wording:

class Namespace::Class;

Why do I have to do this?

You have to do this because the term Namespace::Class is telling the compiler:

...OK, compiler. Go find the namespace named Namespace, and within that refer to the class named Class.

But the compiler doesnt know what you're talking about because it doesn't know any namespace named Namespace. Even if there were a namespace named Namespace, as in:

namespace Namespace
{
};

class Namespace::Class;

it still wouldn't work, because you can't declare a class within a namespace from outside that namespace. You have to be in the namespace.

So, you can in fact forward declare a class within a namespace. Just do this:

namespace Namespace
{
    class Class;
};
John Dibling
A: 

I suppose it's for the same reason you cannot declare nested namespaces in one go like this:

namespace Company::Communications::Sockets {
}

and you have to do this:

namespace Company {
  namespace Communications
    namespace Sockets {
    }
  }
}
Igor Zevaka