¿Cuál es la diferencia entre una clase de plantilla y una plantilla de clase?
¿Cuál es la diferencia entre una clase de plantilla y una plantilla de clase?
Respuestas:
Este es un punto común de confusión para muchos (incluida la página de programación genérica en Wikipedia, algunos tutoriales de C ++ y otras respuestas en esta página). En lo que respecta a C ++, no existe una "clase de plantilla", solo existe una "plantilla de clase". La forma de leer esa frase es "una plantilla para una clase", en contraposición a una "plantilla de función", que es "una plantilla para una función". Nuevamente: las clases no definen plantillas, las plantillas definen clases (y funciones). Por ejemplo, esta es una plantilla , en concreto una plantilla de clase , pero es no una clase :
template<typename T> class MyClassTemplate
{
...
};
La declaración MyClassTemplate<int> es una clase, o pedante, una clase basada en una plantilla. No hay propiedades especiales de una clase basada en una plantilla frente a una clase que no se basa en una plantilla. Las propiedades especiales son de la propia plantilla .
La frase "clase de plantilla" no significa nada, porque la palabra "plantilla" no tiene ningún significado como adjetivo cuando se aplica al sustantivo "clase" en lo que respecta a C ++. Implica la existencia de una clase que es (o define) una plantilla , que no es un concepto que exista en C ++.
Entiendo la confusión común, ya que probablemente se basa en el hecho de que las palabras aparecen en el orden "clase de plantilla" en el idioma real, lo cual es una historia completamente diferente.
Bjarne Stroustrup, el creador de C ++, dice en su libro The C ++ Programming Language 4th edition , 23.2.1 Defining a Template:
Hay personas que hacen distinciones semánticas entre los términos plantilla de clase y clase de plantilla . Yo no; Eso sería demasiado sutil: considere esos términos intercambiables. De manera similar, considero que la plantilla de función es intercambiable con la función de plantilla .
La diferencia es que el término "clase de plantilla" simplemente no existe en el estándar C ++. Es un término utilizado principalmente por personas que piensan que el término "plantilla de clase" es confuso (como las empresas Qt Nokia y anteriormente Trolltech).
El Estándar no tiene un concepto de él, por lo que depende de otras personas hacer la diferencia. Algunas personas lo usan como sinónimo, y otros dicen que el término "clase de plantilla" se refiere a una plantilla de clase instanciada o explícitamente especializada, lo que la haría equivalente al término "especialización de plantilla de clase". Históricamente, tuvo este significado. El Manual de referencia anotado define en la página 343
Una clase generada a partir de una plantilla de clase se denomina clase de plantilla, al igual que una clase definida específicamente con un nombre de clase de plantilla como nombre
El nombre de clase de plantilla no terminal es equivalente al ID de plantilla no terminal utilizado en el estándar actual y se reduce template-name < arguments >.
Familiarizarse con los términos actuales, que es más importante que usar términos antiguos dudosos
// (1) defines a class template
template<typename T> class A { };
// (2) defines a class template explicit specialization
template<> class A<int> { };
// (3) defines a class template partial specialization
template<typename T> class A<T*> { };
// (4) explicitly instantiates A<char>.
template class A<char>;
// (5) implicitly instantiates A<short> (because of the member declaration)
struct D { A<short> a; };
Una clase de plantilla está relacionada con el patrón de diseño del Método de plantilla , mientras que la plantilla de clase es solo una plantilla de clase de "llenar los espacios en blanco".
Una plantilla de clase es una plantilla que se utiliza para generar clases, mientras que una clase de plantilla es una clase producida por una plantilla.
Clase de plantilla: una clase que tiene una definición genérica o una clase con parámetros que no se instancia hasta que el cliente proporciona la información. Se refiere a una jerga para plantillas simples, simplemente clase con plantilla de prefijo y uso de T. Plantilla de clase: la construcción individual de una clase se especifica mediante una plantilla de clase que es casi similar a la forma en que se construyen los objetos individuales utilizando una clase. Se refiere a un objeto de la clase de plantilla Ex- classname objectname (lista de argumentos)
La plantilla de clase es una clase genérica para diferentes tipos de objetos. Básicamente, proporciona una especificación para generar clases basadas en parámetros. Cada vez que se crea un nuevo objeto, tendrá lugar una nueva clase en la memoria para ese propósito. Esto se llama instanciar una plantilla de clase y cada versión instanciada de la clase se llama clase de plantilla.
Eche un vistazo a este artículo (de wg21 y se publicó en 1992) :
Terminología coherente
Gran parte del argumento y el desacuerdo hasta la fecha se ha relacionado con la terminología utilizada en el capítulo que describe las plantillas. La más frecuente ha sido la aplicación variable de 'function-template' y 'template-function' para expresar diferentes ideas e intenciones. Dado que no se aplica un nombre consistente, el resultado es confusión y discusión.
A los efectos de este documento, como propuesta para su adopción formal por parte del comité en discusiones sobre plantillas, y con el propósito de aclarar la documentación; Propongo que adoptemos la formalización, que un '-template' final describe un conjunto de tipos o funciones descritos por una plantilla. Y que una 'plantilla- ' inicial se utiliza para describir la definición de plantilla de parte de una 'plantilla' , como un
'template-member-function'. Así:
- 'function-template': un conjunto de funciones descritas por una plantilla, paramétricas en algún tipo de información proporcionada como argumento para esa plantilla. Por ejemplo :-
template<class T> int nullcheck( T* pT )
{ return ( pT != 0 ); }
- 'class-template': un conjunto de clases descrito por una plantilla, paramétrico en algún tipo de información proporcionada como argumento a esa plantilla. Por ejemplo :-
template<class T> class S {
int i;
public:
int sep_member();
int imm_member()
{ return 2; }
}
- 'template-function': este término ya no está permitido. **
'template-class': este término no está permitido. **
'member-function-template': este término no está permitido, ya que describe una propiedad que actualmente no es compatible con la definición de la plantilla. Usando la convención terminológica anterior, esto describiría un miembro de una plantilla que no es de clase, cuya definición es en sí misma una plantilla. Por ejemplo :-
class Normal { public:
template<class T> int foo(T*pT)
{ return ( pT == 0 ); }
};
Sin embargo, dado que las plantillas están actualmente limitadas al ámbito global, dicha plantilla no es válida.
- 'plantilla-función-miembro-estática':
- 'función-miembro-plantilla':
- 'plantilla-miembro-estático':
- 'template-static-data-member ' template-member ': términos alternativos para la definición de un miembro que aparecen separados de la' class-template 'a la que pertenece. Por ejemplo :-
template<class T> int S<T>::sep_member()
{ return i; }
Normalclase que describe anteriormente: no sabía que tal plantilla de función de miembro estaba prohibida. Es aceptado por todos los compiladores que probé. ¿Qué me estoy perdiendo?