Use ‘class’ o ‘typename’ para los parámetros de la plantilla?

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  ... 

o uno puede escribir esto:

 template  ... 

¿Hay alguna 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 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.

Sin embargo, typename cuenta que, en el caso de los parámetros de plantilla de plantilla , se requiere el uso de class lugar de typename . Ver la respuesta del usuario1428839 a continuación. (Pero este caso particular no es una cuestión de preferencia, es un requisito del idioma). (Esto también cambiará con c++17 )

Stan Lippman habló de esto aquí . Pense que era interesante.

Resumen : Stroustrup utilizó originalmente la class para especificar los tipos en las plantillas para evitar introducir una nueva palabra clave. Algunos en el comité se preocuparon de que esta sobrecarga de la palabra clave generara confusión. Más tarde, el comité introdujo una nueva palabra clave typename para resolver la ambigüedad sintáctica, y decidió permitir que también se utilizara para especificar tipos de plantilla para reducir la confusión, pero para la compatibilidad con versiones anteriores, la class mantuvo su significado sobrecargado.

De acuerdo con Scott Myers, Effective C ++ (3rd ed.) Elemento 42 (que debe, por supuesto, ser la respuesta final) – la diferencia es “nada”.

El consejo es usar “clase” si se espera que T siempre sea una clase, con “nombre de tipo” si se pueden esperar otros tipos (int, char * whatever). Considéralo una pista de uso.

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

 template  

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

 error: expected 'class' before 'Container' 

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

Hay una diferencia, y usted debería preferir la class a typename .

¿Pero por qué?

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

 template 

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

 template  class smart_integer { public: typedef integer_traits 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 ese significado sobrecargado.

Eso ... o solo soy perezoso de corazón. Escribo 'clase' mucho más a menudo que 'nombre de tipo', y por eso me resulta mucho más fácil escribir. O podría ser una señal de que escribo demasiado código OO.

Solo historia pura. Cita de Stan Lippman :

El motivo de las dos palabras clave es histórico. En la especificación de 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, por supuesto, podría romper los progtwigs existentes. No se trató de considerar una nueva palabra clave, sino que no se consideró necesaria dada 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 debería usar typename en lugar de clase ! Vea el enlace para más información, pero piense en el siguiente código:

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

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 las personas usan clases, por lo que probablemente sea más fácil de leer en general.

Hasta donde yo sé, no importa cuál uses. Son equivalentes a los ojos del comstackdor. Utilice el que prefiera. Normalmente uso clase.

Extendiendo el comentario de DarenW

Una vez que el nombre de tipo y la clase no son aceptados para ser muy diferentes, aún puede ser válido para ser estricto en su uso. Use class 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 “hintfullness” o inteligibilidad para otras personas. Y, de hecho, considere que los scripts / software de terceros podrían intentar usar el código / información para adivinar qué está sucediendo con la plantilla (considere la posibilidad de realizar swig).