2009-06-20 36 views
120

Duplicar posible:
Forward declaration of nested types/classes in C++¿Cómo reenvío declarar una clase interna?

que tiene una clase como así ...

class Container { 
public: 
    class Iterator { 
     ... 
    }; 

    ... 
}; 

Por otra parte, quiero pasar un contenedor :: iterador por referencia, pero no quiero incluir el archivo de encabezado. Si intento reenviar declaro la clase, obtengo errores de compilación.

class Container::Iterator; 

class Foo { 
    void Read(Container::Iterator& it); 
}; 

Compilar el código anterior da ...

test.h:3: error: ‘Iterator’ in class ‘Container’ does not name a type 
test.h:5: error: variable or field ‘Foo’ declared void 
test.h:5: error: incomplete type ‘Container’ used in nested name specifier 
test.h:5: error: ‘it’ was not declared in this scope 

¿Cómo puedo declarar adelante esta clase, así que no tengo que incluir el archivo de cabecera que declara la clase de iterador?

Respuesta

102

Esto simplemente no es posible. No puede reenviar declarar una estructura anidada fuera del contenedor. Solo puede reenviar declararlo dentro del contenedor.

Usted tendrá que hacer una de las siguientes

  • hacer que la clase no anidada
  • cambiar su orden de declaración para que la clase anidada está totalmente definida por primera vez
  • crear una clase base común que se pueden usar tanto en la función como implementados por la clase anidada.
+2

La clase base común es la solución más utilizada en mi extremo. – Coyote

+0

Puede usar un amigo para solucionar este problema, si lo desea. –

+1

Eso está mal: http: //en.cppreference.com/w/cpp/language/nested_types – Nikerboker

18

no creo adelante declarando clase interna en una de las obras incompletas de clase (porque sin la definición de clase, no hay manera de saber si realmente es una clase interna). Por lo que usted tiene que incluir la definición de contenedor, con una clase interna hacia adelante declaró:

class Container { 
public: 
    class Iterator; 
}; 

Luego, en una cabecera separada, implemento de contenedores :: iterador:

class Container::Iterator { 
}; 

Entonces sólo el # include cabecera contenedor (o no se preocupan por delante declarar y solo incluyen ambos)

+4

Buena respuesta, excepto la parte en el paréntesis del primer párrafo. El "no hay manera de saber si realmente hay una clase interna" no tiene sentido en este contexto y es dudoso que sea preciso. El objetivo de una declaración directa es que le está diciendo al compilador que hay una clase (o en este caso, una clase interna). Esa afirmación específica tuya sería igual de verdadera para las clases normales y significaría que no puedes reenviar declarar nada. – Aaron

1

no conozco ninguna manera de hacer exactamente lo que quiere, pero aquí es una solución temporal, si usted está dispuesto a utilizar plantillas:

// Foo.h 
struct Foo 
{ 
    export template<class T> void Read(T it); 
}; 

// Foo.cpp 
#include "Foo.h" 
#include "Container.h" 
/* 
struct Container 
{ 
    struct Inner { }; 
}; 
*/ 
export template<> 
    void Foo::Read<Container::Inner>(Container::Inner& it) 
{ 

} 

#include "Foo.h" 
int main() 
{ 
    Foo f; 
    Container::Inner i; 
    f.Read(i); // ok 
    f.Read(3); // error 
} 

Con suerte, este idioma podría ser de alguna utilidad para usted (y es de esperar que el compilador está basado en EDG e implementa la exportación;)).

Cuestiones relacionadas