2010-12-31 20 views
19

Hay 2 clases que no son de plantilla A, B que tienen algunos métodos de plantilla estática.Error: tipo incompleto utilizado en el especificador de nombre anidado

de la clase A método estático en B se llama y de la clase B método estático de A se llama. El código fuente sólo para ilustración (código no real) ...

A.h

#include "B.h" 
class A 
{ 
public: 
    template <class T> 
    void f1() 
    { 
     T var1= ...; 
     T var2 = B::f4(T); 
    } 

    template <class T> 
    T f2() 
    { 
     return ... 
    } 
}; 

#include "A.h" 
class B 
{ 
public: 
    template <class T> 
    void f3() 
    { 
     T var1= ...; 
     T var2 = A::f2(T); //Error 
    } 

    template <class T> 
    T f4() 
    { 
     return ... 
    } 
}; 

estoy teniendo problemas con el compilador g ++ en NetBeans. Durante la compilación se produce el siguiente error: Error: tipo A incompleto utilizado en el especificador de nombre anidado, g ++.

Traté de agregar declaraciones hacia adelante en ambas clases, pero nada fue exitoso.

Hay un error de más edad:

http://gcc.gnu.org/ml/gcc-bugs/2005-02/msg01383.html

Respuesta

0

Su problema es la dependencia de cabecera circular.

+29

Y la solución es ...? –

+1

Aquellos que votan en contra necesitan declarar contra lo que se oponen. Porque es una respuesta correcta a la pregunta OP. El OP no pidió explicaciones sobre cómo resolver las dependencias circulares del encabezado, esas trivialidades se explican en cada libro. –

+0

http://stackoverflow.com/help/how-to-answer – peetonn

7

Tiene una dependencia circular entre sus archivos de encabezado. Desde sus clases están tan estrechamente entrelazados, sugeriría su fusión en un archivo de cabecera única, estructurado así:

class A 
{ 
public: 
    template <class T> 
    void f1(); 
}; 

class B 
{ 
    ... 
}; 

template <class T> 
void A::f1() 
{ 
    // Use full definition of class B 
} 

Si usted insiste en el uso de ficheros de cabeceras para A y B (que no será realmente hacer cualquier diferencia, ya que terminan incluyéndose entre ellos), tendrá que reestructurarlos para que uno de los encabezados no incluya al otro, por lo que al menos una de las funciones de plantilla dependientes deberá definirse en un archivo separado. Por ejemplo:

// File "a_no_b.h" 
class A 
{ 
public: 
    template <typename T> 
    void f1(); 
}; 

// File "b_no_a.h" 
class B 
{ 
public: 
    template <typename T> 
    void f3(); 
}; 

// File "a.h" 
#include "a_no_b.h" 
#include "b_no_a.h" 

template <typename T> 
void A::f1() 
{ 
    // Use full definition of class B 
} 

// File "b.h" 
#include "b_no_a.h" 
#include "a_no_b.h" 

template <typename T> 
void B::f3() 
{ 
    // Use full definition of class A 
} 
+0

Gracias, funciona bien. He tenido ambas directivas de inclusión antes de las declaraciones de clase ... – Ian

4

Debido a que existe una dependencia circular, es necesario organizar cuidadosamente las declaraciones de clases A y B por lo que ambos están declaradas antes se definen las funciones miembro.

Aquí es A.h:

#ifndef A_H 
#define A_H 1 
class A 
{ 
public: 
    template <class T> 
    void f1(); 

    template <class T> 
    T f2(); 
}; 

#include "B.h" 

template <class T> 
void A::f1() 
{ 
    T var1= ...; 
    T var2 = B::f4(T); 
} 

template <class T> 
T A::f2() 
{ 
    return ... 
} 

#endif 

Aquí es B.h:

#ifndef B_H 
#define B_H 1 
class B 
{ 
public: 
    template <class T> 
    void f3(); 

    template <class T> 
    T f4(); 
}; 

#include "A.h" 

template <class T> 
void B::f3() 
{ 
    T var1= ...; 
    T var2 = A::f2(T); 
} 

template <class T> 
T B::f4() 
{ 
    return ... 
} 

#endif 

Con este enfoque, usted será capaz de incluir ya sea A.h o B.h primero y no tiene un problema.

+0

Gracias, funciona bien. He tenido ambas directivas de inclusión antes de las declaraciones de clase ... – Ian

Cuestiones relacionadas