2010-09-26 12 views
8

Yo sé que puedo hacer¿Qué puedo "reenviar declarar" en C++?

class Foo; 

y probablemente

struct Bar; 

y funciones globales

bool IsValid(int iVal); 

Qué pasa con una enumeración escrita a máquina? ¿Qué pasa con una enumeración tipada dentro de una clase no declarada? ¿Qué pasa con una función con una clase no declarada? ¿Qué pasa con un miembro estático dentro de una clase no declarada? ¿Qué hay de estos dentro de un espacio de nombres desconocido? ¿Me estoy perdiendo algo más que pueda ser declarado adelante?

+6

¿Por qué no lo intentas y ves? –

+0

enum va a poder reenviar declarar en C++ 0x. y no puede reenviar "parcialmente" las clases (declaración de métodos) – erjot

+0

Tiendo a poner enumeraciones escritas dentro de las clases que las "definen". Luego encuentro problemas con el compilador de "dependencia circular" con dos clases que hacen referencia a las enumeraciones de cada una. – franji1

Respuesta

12

Puede reenviar declarar

  • plantillas, incluyendo especializaciones parciales
  • especializaciones explícitos
  • clases anidadas (esto incluye estructuras, clases "reales" y sindicatos)
  • clases no anidados y locales
  • Variables ("extern int a;")
  • Funciones

Si por "declaración directa" significa estrictamente "declarar pero no definir" también puede reenviar declarar funciones de miembro. Pero no puede redeclararlos en su definición de clase una vez que se declaran. No puede reenviar-declarar enumeraciones. No estoy seguro de si me perdí algo.

Tenga en cuenta que todas las declaraciones de reenvío enumeradas anteriormente, excepto las especializaciones parciales y explícitas, deben declararse utilizando un nombre no calificado y que las funciones de miembro y anidadas solo pueden declararse pero no definirse en su definición de clase.

class A { }; 
class A::B; // not legal 

namespace A { } 
void A::f(); // not legal 

namespace A { void f(); } // legal 

class B { class C; }; // legal 
class B::C; // declaration-only not legal 

class D { template<typename T> class E; }; 
template<typename T> class D::E<T*>; // legal (c.f. 14.5.4/6) 
+1

Creo que olvidó la nueva 'clase enum' de C++ 0x. El punto de precisar la representación subyacente era hacer que sea forward-declarable si no recuerdo mal. –

+0

¿Hay algún punto en la declaración anticipada de una especialización parcial? Las especializaciones parciales no son visibles durante la búsqueda de nombres, y se resuelven en el momento de la creación de instancias de la plantilla, en cuyo punto deben estar completamente definidas de todos modos. – willj

+0

@willj es permisible tener una plantilla indefinida en ciertos contextos (forward declarada) sin error, pero haciendo una instanciación cuando se define la plantilla. Las llamadas de ADL donde el tipo de argumento está asociado con la especialización parcial es un ejemplo. Si no lo hubiera anunciado, pero ya definió la plantilla principal, en su lugar se creará una instancia de la plantilla principal. –

Cuestiones relacionadas