Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring nested classes before they are defined

Tags:

c++

I can declare a pointer to a class that hasn't yet been defined, like this:

class A ;
A* p ;

But how do I do this for a nested class? I want to do this:

class A ;
class A::B ; // error: 'B' in class 'A' does not name a type
A::B* p ;

But it doesn't compile (using g++ 4.5.2). Is there any way to make this work?

like image 808
TonyK Avatar asked Nov 17 '11 11:11

TonyK


2 Answers

There are a number of parts of C++03 that disallow forward declarations of nested classes. In particular, § 7.1.5.3 Elaborated type specifiers:

  1. If an elaborated-type-specifier is the sole constituent of a declaration, the declaration is ill-formed unless it is an explicit specialization (14.7.3), an explicit instantiation (14.7.2) or it has one of the following forms:

    class-key identifier ; 
    friend class-key ::optidentifier ; 
    friend class-key ::opttemplate-id ; 
    friend class-key ::optnested-name-specifier identifier ; 
    friend class-key ::optnested-name-specifier templateopttemplate-id ;
    
  2. 3.4.4 describes how name lookup proceeds for the identifier in an elaborated-type-specifier. If the identifier resolves to a class-name or enum-name, the elaborated-type-specifier introduces it into the declaration the same way a simple-type-specifier introduces its type-name. [...] If name lookup does not find a declaration for the name, the elaborated-type-specifier is ill-formed unless it is of the simple form class-key identifier in which case the identifier is declared as described in 3.3.1.

In short, when an identifier is scoped, the compiler must try to resolve the identifier. When the scope is a class, the compiler must look up the declaration for the identifier in the outer class. When the outer class hasn't yet been defined, this can't be done and the result is an ill-formed program.

like image 127
outis Avatar answered Sep 26 '22 16:09

outis


Consider a namespace instead of nested class.

class A;
A * pa;
namespace A_help
{
   class B;
} // namespace A_help
A_help::B * pb;
like image 26
Alexey Malistov Avatar answered Sep 22 '22 16:09

Alexey Malistov