2010-12-05 11 views
7

me escribió una clase de plantilla que está dando error de compilaciónC++ error de compilación plantilla - tipo o función recursiva dependencia

template<class T> 
class Entity 
{ 
    string EntityName; 
    int EntitySize; 
    Entity<T*> pPrev; 
    Entity<T*> pNext; 
public: 
    Entity<T>(const string & name, int size) 
    { 
     EntityName = name; 
     EntitySize = size; 
    } 
    //member functions 
}; 

estoy usando MSVC++ 2008, y el error es:

fatal error C1202: recursive type or function dependency context too complex

tengo no se ha escrito ninguna función recursiva en mi clase. Entonces, ¿por qué este error? Por favor ayuda.

Respuesta

11

Muy bien. Te estoy explicando el problema al que te enfrentas. Pero primero lo primero. Usted dijo:

I wrote a template class which is giving compilation error

En primer lugar, en lo que se refiere a C++, no hay tal cosa como una "clase de plantilla," sólo hay una "plantilla de clase." La forma de leer esa frase es "una plantilla para una clase", en oposición a una "plantilla de función", que es "una plantilla para una función". De nuevo: las clases no definen plantillas, las plantillas definen clases (y funciones). * Citado de here.

Ahora, vamos a ver el error:

fatal error C1202: recursive type or function dependency context too complex

El error dice todo. $14.7.1 del estándar explica muy bien la causa de su problema, brindándole incluso un ejemplo que es muy similar a lo que está haciendo. Así que ni siquiera necesito escribir una sola palabra propia.Aquí es $14.7.1

4 There is an implementation-defined quantity that specifies the limit on the total depth of recursive instantiations, which could involve more than one template. The result of an infinite recursion in instantiation is undefined. [ Example:

template < class T > class X { 
X<T >* p; // OK 
X<T*> a; //implicit generation of X<T> requires 
     //the implicit instantiation of X<T*> which requires 
     //the implicit instantiation of X<T**> which ... 
}; 

—end example ]

Por favor, lea el comentario con X<T*> a, que es casi lo mismo con usted también. Así que el problema no se debe a la función recursiva, es más bien debido a instanciación recursiva de plantilla de clase, haciendo de estas líneas:

Entity<T*> pPrev; 
    Entity<T*> pNext; 

Esperanza, que resuelve su problema!


EDIT: Pero me pregunto ¿qué estás tratando de lograr con Entity<T*> pPrev? Parece que es un error tipográfico, y probablemente quieras escribir Entity<T>* pPrev. Lo mismo con pNext. ¿Es eso así?

Y un consejo para mejorar el diseño: Use la lista de Inicialización de miembros, en lugar de la Asignación. Es decir, escribir el constructor de la siguiente manera,

Entity<T>(const string & name, int size) : EntityName(name), EntitySize(size) 
    { 
     //all assignments moved to initialization list. 
    } 

Lea esto: Why should I prefer to use member initialization list?

+0

era un error tipográfico. Corregí eso y solucionó el error. muchas gracias. –

-1

Has escrito un tipo recursivo. La entidad tiene otros miembros de Entidad. Debe cambiar los miembros de la Entidad en un puntero o referencia.

6

Lea el mensaje de error más de cerca. Lo "demasiado complejo" no es una función recursiva, es una dependencia de tipo o función recursiva. El tipo Entity<T*> depende del tipo Entity<T>, recursivamente. Cuando el compilador intente generar el código para Entity<int>, tendrá que averiguar Entity<int*> (para implementar los miembros pPrev y pNext), lo que significa que tendrá que averiguar Entity<int**>, etc. - infinitamente. Eso no está permitido.

Pero así es como el compilador sabe que algo está mal. No sabe lo que está mal, porque no puede pensar en cómo programar. (Si pudiera, simplemente escribiría su programa para usted)

El error lógico es que Entity<T*> significa "un objeto que es una entidad con tipo de plantilla puntero-a-T". Lo que realmente quería, para hacer una lista vinculada, es "un puntero a un objeto que es una Entidad con plantilla tipo T". Eso se deletrea Entity<T>*, con * fuera de los corchetes angulares.

Pero el verdadero problema es que está tratando de crear su propia lista vinculada. No hagas eso. Use los contenedores de biblioteca estándar. Si es lo suficientemente inteligente como para usar std::string, debe ser lo suficientemente inteligente como para usar los contenedores (std::vector, std::list, etc. - en cierto sentido, std::string también es un contenedor, aunque de propósito muy especial).

1

Cambio

 
    Entity<T*> pPrev; 
    Entity<T*> pNext; 

a

 
    Entity<T> *pPrev; 
    Entity<T> *pNext; 

Su tipo de definición es recursiva ...

2

La definición de su plantilla es infinitamente recursiva. Define la clase de plantilla Entity<T> que contiene objetos del tipo Entity<T*> como miembros. Los objetos Entity<T*> tendrán, según la misma definición, objetos del tipo Entity<T**>. Este último a su vez contendrá objetos del tipo Entity<T***> y así sucesivamente, como infinitum. En otras palabras, su definición de plantilla infinitamente recursiva no tiene sentido.

Termine la recursión o piense qué es lo que realmente está tratando de implementar. Sospecho fuertemente que se suponía que las definiciones de sus miembros tenían el tipo Entity<T>*, no el Entity<T*>.

Cuestiones relacionadas