2011-04-26 12 views
5

Cuando tratando de compilar este código (CRTP-like) con GCC 4.6.0:plantilla de clase llamado X en la clase de plantilla

template<template<class> class T> struct A; 

template<class T> 
struct B: A<B<T>::template X> { 
    template <class U> struct X { U mem; }; 
}; 

B<int> a;

tengo la ErrorMessage "test.cpp: 3: 26: error: ninguna plantilla de clase llamada 'X' en 'struct B <int>' ". ¿Por qué X parece ser invisible fuera de la definición de la clase?

+0

Mi compilador tiene un problema con esto: : A < B :: plantilla X> La X es un identificador no declarado. Francamente, estoy confundido por su sintaxis, ¿qué se supone que es B :: plantilla? Además de que nunca he visto: plantilla clase T. En todo caso, creo que voy a aprender algo de ti; ¿Puedes explicar la importancia de la sintaxis? ¿Qué hacen? – leetNightshade

+0

No estoy seguro, pero quizás la respuesta de Johannes sobre este tema podría ayudar aquí: http://stackoverflow.com/questions/4420828/another-bug-in-g-clang-c-templates-are-fun – Nawaz

+0

@leetNightshade : No estoy seguro pero creo que tu mensaje de error está diciendo lo mismo que el mío: que X no es visible fuera de B (así es como lo entiendo de todos modos). Acerca de su segunda pregunta: "plantilla clase T" significa que T es una plantilla en sí misma. De esa manera puedes usar algo como T dentro de la definición de clase de A. –

Respuesta

4

Como Emile Cormier señala correctamente here El problema es que en el lugar de creación de instancias de A, B sigue siendo un tipo incompleto, y no se puede utilizar la plantilla interior.

La solución para eso es mover la plantilla X fuera de la plantilla B. Si es independiente de lo particular de instancias T de la plantilla B, sólo se mueven al nivel de espacio de nombres, si depende de la creación de instancias, puede utilizar caracteres de tipo:

template <typename T> 
struct inner_template 
{ 
    template <typename U> class tmpl { U mem; }; // can specialize for particular T's 
}; 
template <typename T> 
struct B : A< inner_template<T>::template tmpl > 
{ 
}; 
2

struct B sigue considerándose un tipo incompleto cuando especifica A<B<T>::template X> como clase base.

1

Está intentando usar un miembro de B como padre de B creando una situación recursiva. Por ejemplo, esto no compila bien:

template<template<class> class T> struct A {}; 

struct B : public A<B::nested> 
{ 
     struct nested {}; 
}; 
+1

Eso no es verdad: estoy pasando B como un parámetro de plantilla, no heredaré de él. –

+0

@Tom De Caluwé Cambié mi respuesta para mostrar que, incluso como parámetro de plantilla, todavía se trata como un tipo incompleto que no se puede utilizar como parámetro de plantilla. –

Cuestiones relacionadas