2010-09-26 19 views
8

C++ estándarnombre de la plantilla y la plantilla Identificación del

Sección 14/2:

En una declaración plantilla de función, la declarador-id deberá ser un nombre-plantilla (es decir, no es template-id). [Nota: en una declaración de plantilla de clase , si el declarador-id es una plantilla -id, la declaración declara una clase plantilla de especialización parcial.

¿Cuál es la diferencia entre un template-name, template-id y una type-id?

¿La cita anterior quiere decir que no puede escribir algo así como

template <> 
void templatefunction<int>(){ // ...} 

o he entendido mal el punto?

Respuesta

29

nombre-plantilla es el nombre de la plantilla. En su ejemplo, templatefunction es un plantilla-nombre.

plantilla-id es el nombre de la plantilla con la lista de argumentos de la plantilla. En su ejemplo, templatefunction<int> es template-id. Una plantilla-id nombra una especialización de plantilla.

A tipo-id nombra un tipo. Un template-id es un type-id; un plantilla-nombre no es (porque no nombra un tipo, sino que nombra una plantilla).

El texto que cita de 14/2 se refiere a plantilla-declaración, que declara una plantilla primaria. Su ejemplo no es plantilla-declaración, es explícita-especialización (14.7.3/1).

2

De C++ Templates: The Complete Guide Por David Vandevoorde, Nicolai M. Josuttis

8.3

argumentos de plantilla explícita: Un nombre de la plantilla puede ser seguido por valores de los argumentos de plantilla explícita entre corchetes angulares. El nombre resultante se llama template-id.

Por ejemplo:

template <typename T> 
struct Demo{ 
    // ... 
}; 

int main() 
{ 
    Demo <int> d; // Demo is the template name, Demo<int> is the template-id 
    // ... 
} 

En una declaración plantilla de función, la declarador-id deberá ser una nombre de la plantilla (es decir, no una plantilla-id).

Por ejemplo (por lo que he entendido):

class A { 
public: 
    template <typename T> void f(T); 
    template <typename T> struct X { }; 
}; 
class B : public A { 
public: 
    using A::f;  // fine 
    using A::X  // fine 

}; 
class C : public A { 
public: 
    using A::f<int>;  // ill formed, declarator-id shall not be a template id 
    using A::X<double> // ill formed, declarator-id shall not be a template id 

}; 

Alguien por favor me corrija si estoy equivocado.

6

Un declarator-id es el elemento sintáctico que especifica el nombre en una simple declaración ("nombre de tipo;"). En la siguiente "A" y "B :: C" es la declarador-id

int A; 
int B::C; 
int A(); 
int *A; 
int A[42]; 
template<typename T> void A(); 

Un tipo-id sintácticamente es más o menos una simple declaración donde el declarador-ID no existe. Un ID de tipo se utiliza como el elemento sintáctico en un argumento de tipo de plantilla y en un molde.

int // type-id 
int* // type-id 
int[] // type-id 
int() // type-id 
int(*)() // type-id 

Una plantilla-Nombre es el nombre de una plantilla. Sintácticamente aparece antes de una lista de argumento de plantilla. La cita anterior hace mal uso de "template-name" y "declarator-id", porque un template-name es un identificador simple y no contiene ningún calificador. C++ 0x ha cambiado el texto a

En una declaración de plantilla de función, el último componente de la identificación del declarante será una plantilla-nombre o operador-función-identificación (es decir, no una plantilla-identificación) .

(La última parte aparece en casos como operator+()). Incluso el texto de C++ 0x falla en algunos casos; consulte this defect report.

El mal uso de "declarator-id" ocurre en la nota. La nota fue sustituido por C++ 0x con

[Nota: en una declaración de plantilla de clase, si el nombre de la clase es un ... - nota final]

En declaraciones plantilla clase, el El nombre especificado sintácticamente es un nombre de clase en lugar de un declarator-id. La relación del nombre de clase y declarador-id es el siguiente (muy simplificada ...)

class class-name { ... } declarator-id; 
class foo  { ... } bar; 

En declaraciones plantilla de clase, puede que no haya una sentencia declarativa-id especificado.


Una plantilla-id es un nombre de plantilla seguido de una lista de argumento de plantilla.


La cita significa que en una función de declaración plantilla, el nombre no debe ser una plantilla-id. En su ejemplo, declara una función en lugar de una plantilla.Sin embargo, todavía hay casos en que una especialización explícita declara una plantilla. Pero eso solo puede suceder para las plantillas de funciones miembro

template<typename T> 
struct A { 
    template<typename U> 
    void f(); 
}; 

// this explicit specialization *contains* a template declaration and 
// declares an identifier (a template-name) qualified by A<int>:: 
template<> template<typename U> 
void A<int>::f() { } 
Cuestiones relacionadas