the template guide geeksforgeeks example c++ templates

c++ - template - ¿Usar ''clase'' o ''nombre de tipo'' para los parámetros de la plantilla?



template function c++ (10)

Posible duplicado:
Diferencia de C ++ de las palabras clave ''typename'' y ''class'' en las plantillas

Al definir una plantilla de función o plantilla de clase en C ++, uno puede escribir esto:

template <class T> ...

o uno puede escribir esto:

template <typename T> ...

¿Hay una buena razón para preferir uno sobre el otro?

Acepté la respuesta más popular (e interesante), pero la respuesta real parece ser "No, no hay una buena razón para preferir una sobre la otra".

  • Son equivalentes (excepto como se indica a continuación).
  • Algunas personas tienen razones para usar siempre el nombre typename .
  • Algunas personas tienen razones para usar siempre la class .
  • Algunas personas tienen razones para usar ambos.
  • A algunas personas no les importa cuál usan.

Tenga en cuenta, sin embargo, que en el caso de los parámetros de plantilla de plantilla , se requiere el uso de class lugar de typename . Ver usuario1428839''s respuesta abajo. (Pero este caso particular no es una cuestión de preferencia, es un requisito del lenguaje.) (También esto cambiará con c++17 )


Hay una diferencia, y deberías preferir la class al nombre typename .

¿Pero por qué?

typename es ilegal para los argumentos de la plantilla de la plantilla, para ser consistente, debe usar la class :

template<template<class> typename MyTemplate, class Bar> class Foo { }; // :( template<template<class> class MyTemplate, class Bar> class Foo { }; // :)


Como una adición a todas las publicaciones anteriores, el uso de la palabra clave de class es forzado (hasta e incluyendo C ++ 14) cuando se trata de parámetros de plantilla de plantilla , por ejemplo:

template <template <typename, typename> class Container, typename Type> class MyContainer: public Container<Type, std::allocator<Type>> { /*...*/ };

En este ejemplo, typename Container habría generado un error de compilación, algo como esto:

error: expected ''class'' before ''Container''


En respuesta a Mike B , prefiero usar ''clase'' ya que, dentro de una plantilla, ''nombre de tipo'' tiene un significado sobrecargado, pero ''clase'' no. Tome este ejemplo de tipo entero comprobado:

template <class IntegerType> class smart_integer { public: typedef integer_traits<Integer> traits; IntegerType operator+=(IntegerType value){ typedef typename traits::larger_integer_t larger_t; larger_t interm = larger_t(myValue) + larger_t(value); if(interm > traits::max() || interm < traits::min()) throw overflow(); myValue = IntegerType(interm); } }

larger_integer_t es un nombre dependiente, por lo que requiere que ''typename'' lo preceda para que el analizador pueda reconocer que larger_integer_t es un tipo. clase , por otro lado, no tiene tal significado sobrecargado.

Eso ... o simplemente soy flojo de corazón. Escribo "clase" con mucha más frecuencia que "nombre de tipo" y, por lo tanto, me resulta mucho más fácil escribir. O podría ser una señal de que escribo demasiado código OO.


Extendiendo el comentario de DarenW.

Una vez que no se acepta que typename y class sean muy diferentes, podría seguir siendo válido para ser estrictos en su uso. Use clase solo si es realmente una clase, y typename cuando es un tipo básico, como char .

Estos tipos también son aceptados en lugar de typename

plantilla < char myc = ''/''>

que sería en este caso incluso superior a typename o class.

Piense en la "inseguridad" o la inteligibilidad para otras personas. Y, en realidad, considere que los software / scripts de terceros pueden intentar usar el código / información para adivinar qué está sucediendo con la plantilla (considere swig).


No importa en absoluto, pero la clase hace que parezca que T solo puede ser una clase, mientras que, por supuesto, puede ser de cualquier tipo. Así que typename es más preciso. Por otro lado, la mayoría de la gente usa la clase, por lo que probablemente sea más fácil de leer en general.


Por lo que sé, no importa cuál uses. Son equivalentes a los ojos del compilador. Usa el que prefieras. Normalmente uso la clase.


Prefiero usar typename porque no soy fanático de las palabras clave sobrecargadas (jeez, ¿cuántos significados diferentes tiene la static para diferentes contextos?).


Sólo pura historia. Cita de Stan Lippman :

La razón de las dos palabras clave es histórica. En la especificación de la plantilla original, Stroustrup reutilizó la palabra clave de clase existente para especificar un parámetro de tipo en lugar de introducir una nueva palabra clave que podría, por supuesto, romper los programas existentes. No era que no se considerara una nueva palabra clave, sino que no se consideraba necesaria debido a su posible interrupción. Y hasta el estándar ISO-C ++, esta era la única forma de declarar un parámetro de tipo.

¡Pero uno debe usar el nombre de tipo en lugar de la clase ! Vea el enlace para obtener más información, pero piense en el siguiente código:

template <class T> class Demonstration { public: void method() { T::A *aObj; // oops ... };


Según Scott Myers, Effective C ++ (3ª ed.), Punto 42 (que, por supuesto, debe ser la respuesta definitiva), la diferencia es "nada".

Se recomienda usar "clase" si se espera que T siempre sea una clase, con "nombre de tipo" si se pueden esperar otros tipos (int, char * como sea). Considérelo como una sugerencia de uso.


Stan Lippman habló de esto here . Pense que era interesante.

Resumen : Stroustrup utilizó originalmente la class para especificar tipos en plantillas para evitar la introducción de una nueva palabra clave. A algunos en el comité les preocupaba que esta sobrecarga de la palabra clave generara confusión. Más tarde, el comité introdujo un nuevo nombre de palabra clave para resolver la ambigüedad sintáctica y decidió permitir que también se usara para especificar tipos de plantillas para reducir la confusión, pero para la compatibilidad con versiones anteriores, la class mantuvo su significado sobrecargado.