Pregunta Use 'class' o 'typename' para los parámetros de la plantilla? [duplicar]


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 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 class.
  • Algunas personas tienen razones para usar ambos.
  • A algunas personas no les importa cuál usan.

Tenga en cuenta, sin embargo, en el caso de Plantilla de plantilla parámetros, uso de class en lugar de typename es requerido. Ver La respuesta de user1428839 abajo. (Pero este caso particular no es una cuestión de preferencia, es un requisito del idioma.) (También esto cambiará con c++17)


522
2017-10-17 17:47


origen


Respuestas:


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

Resumen: Stroustrup originalmente utilizado class para especificar tipos en 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ó dejar que también se use para especificar tipos de plantillas para reducir la confusión, pero para la compatibilidad con versiones anteriores, class mantuvo su significado sobrecargado.


354
2017-10-17 17:52



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.


284
2017-10-17 17:52



Como una adición a todas las publicaciones anteriores, el uso del class palabra clave es forzado (hasta e incluyendo C ++ 14) cuando se trata de Plantilla de plantilla parámetros, 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'

136
2017-10-17 20:21



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


45
2017-10-17 19:26



Ahí es una diferencia, y deberías preferir class a typename.

¿Pero por qué?

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

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

12
2017-10-17 17:47



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


9



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 programas 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 escribe un nombre más bien que clase! Vea el enlace para más información, pero piense en el siguiente código:

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

9



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.


7