Domanda

My forward declaration doesnt work if i do it like this:

class Manager::TagManager;

namespace UI
{

    class Example
    {
    public:
    ...

    Manager::TagManager* tagManager_;


    };
}

it says use of undefined type. However it works fine like so:

namespace Manager
{
     class TagManager;
}

//same stuff follows

So whats the difference? is "class Manager::TagManager;" not a declaration of TagManager in namespace Manager?

È stato utile?

Soluzione

A rhetorical question: how would you expect the compiler to know whether class Manager::TagManager is a declaration of class TagManager in namespace Manager or a declaration of nested class TagManager in enclosing class Manager? The compiler never heard about Manager before. It has no idea whether it is a class or a namespace. This is what the compiler is trying to tell you by that error message. It actually assumes that Manager is a class type (not a namespace), which has not been defined.

However, even if it knew what Manager was, it still wouldn't work. In C++ qualified names like Name1::Name2 can only be used to refer to existing (i.e. already declared) entities. You cannot use qualified names to declare new entities.

That means that a forward declaration of an entity that belongs to a namespace can only be done by reopening that namespace. A forward declaration of an entity that is nested into a class can only be done inside the definition of the enclosing class.

With entities in namespaces it is relatively easy, since you can reopen namespaces as many times as you want. With nested entities in classes you get only one chance.

Altri suggerimenti

Unfortunately it is, in my opinion, a design flaw with the language. It should work the same either way, except it doesn't.

No, you never told the compiler that Manager is a namespace. It could be class Manager. (That is probably why it says "undefined type," the error message is not considering the possibility that it is a namespace.)

You can't add a member to anything outside the scope of its own definition. It would break separation of concerns if you could declare something in a namespace without a namespace declaration.

If you must have the name Manager::TagManager work without a declaration of that specific class in Manager, you can use a using namespace declaration inside Manager and declare the class in another namespace. There are occasionally other ways around the rule that things must be declared in their enclosing entity, but they are just name lookup hacks and do not alter what owns or contains what.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top