views:

370

answers:

5

Is it possible to forward-declare a nested class, then use it as the type for a concrete (not pointer to/reference to) data member of the outer class?

I.E.

class Outer;

class Outer::MaybeThisWay   // Error: Outer is undefined
{
};

class Outer
{
 MaybeThisWay x;

 class MaybeThatOtherWay;

 MaybeThatOtherWay y;   // Error: MaybeThatOtherWay is undefined
};
+1  A: 

No, but what's wrong with

class Outer {
public:  //or protected or private
    class Inner {
    };

private:
    Inner foo;
};

Forward declaring doesn't make sense here, unless I'm missing something (which is possible seeing as your question is lacking in a lot of details)

Remember, if a class is forward declared then you can only declare references to or pointers to an object of the forward declared type. You can't do anything else with it, including accessing it's members or functions.

Glen
+1  A: 

If a class has been forward-declared (but you don't have the full definition yet) then you can only declare a pointer to it, because the compiler doesn't yet know the size of the class (nor the names of its fields or methods).

Ken Bloom
A: 

If you declare an attribute of type MaybeThatOtherWay, not a reference nor a pointer, the compiler must know the full definition of the class to determine the size of the outer class. Thus, you can't use forward declaration and that kind of field declaration, whether it's a nested class or not.

Seb
+2  A: 

You can't forward-declare a nested class like that.

Depending on what you're trying to do, maybe you can use a namespace rather than a class on the outer layer. You can forward-declare such a class no problem:

namespace Outer {
   struct Inner; 
};

Outer::Inner* sweets;  // Outer::Inner is incomplete so 
                       // I can only make a pointer to it

If your Outer absolutely must be a class, and you can't shoe-horn it into a namespace, then you'll need for Outer to be a complete type in the context where you forward declare Inner.

class Outer
{
   class Inner;  // Inner forward-declared
};  // Outer is fully-defined now

Outer yes;  // Outer is complete, you can make instances of it
Outer::Inner* fun;  // Inner is incomplete, you can only make 
                    // pointers/references to it

class Outer::Inner 
{
};  // now Inner is fully-defined too

Outer::Inner win;  // Now I can make instances of Inner too
janks
A: 

There is no way to forward declare a nested class without fully specifying the containing class. This little trick kinda fixes the problem though

class Outer_Inner
{
};

class Outer
{
public:
   typedef Outer_Inner Inner;
};

This works for me as in my naming convention Outer_Inner isn't a valid class name, so it's obvious that it refers to an nested class.

You still can't forward declare the nested class like this:

class Outer::Inner;

But at least it can be forward declared with:

class Outer_Inner;

If you don't like the way Outer_Inner looks you could adopt a naming convention for nested classes that better suits your tastes. Outer__Inner, Outer_nested_Inner, etc.

caspin