typenamey classson intercambiables en el caso básico de especificar una plantilla:
template<class T>
class Foo
{
};
y
template<typename T>
class Foo
{
};
son equivalentes
Dicho esto, hay casos específicos en los que hay una diferencia entre typenamey class.
El primero es en el caso de los tipos dependientes. typenamese usa para declarar cuando se hace referencia a un tipo anidado que depende de otro parámetro de plantilla, como typedefen este ejemplo:
template<typename param_t>
class Foo
{
typedef typename param_t::baz sub_t;
};
El segundo que realmente muestra en su pregunta, aunque es posible que no se dé cuenta:
template < template < typename, typename > class Container, typename Type >
Al especificar una plantilla de la plantilla , la classpalabra clave debe ser utilizado como anteriormente - es no intercambiable con typenameen este caso (nota: puesto que C ++ 17 ambas palabras clave se les permite en este caso) .
También debe usar classcuando crea una instancia explícitamente de una plantilla:
template class Foo<int>;
Estoy seguro de que hay otros casos que me he perdido, pero la conclusión es: estas dos palabras clave no son equivalentes, y estos son algunos casos comunes en los que necesita usar uno u otro.
template <typename T> typename Foo {};, porque Foo <T> es definitivamente una clase.std::vector<int>::value_typeno es un tipo dependiente, no lo necesitatypenameallí, solo lo necesita si un tipo depende de un parámetro de plantilla, por ejemplotemplate<class T> struct C { typedef typename std::vector<T>::value_type type; };param_tno es un tipo dependiente. Los tipos dependientes son nombres que dependen de un parámetro de plantilla , por ejemplofoo<param_t>::some_type, no parámetros de plantilla en sí.typename, es decirtemplate <typename> typename C.GCC 5, G ++ ahora permite typename en un parámetro de plantilla de plantilla .Para nombrar parámetros de plantilla,
typenameyclassson equivalentes. §14.1.2:typenamesin embargo, es posible en otro contexto cuando se usan plantillas, para insinuar al compilador que se está refiriendo a un tipo dependiente. §14.6.2:Ejemplo:
Sin
typenameel compilador no se puede decir en general si se refiere a un tipo o no.fuente
Si bien no existe una diferencia técnica, he visto que los dos denotan cosas ligeramente diferentes.
Para una plantilla que debe aceptar cualquier tipo como T, incluidas las incorporadas (como una matriz)
Para una plantilla que solo funcionará donde T es una clase real.
Pero tenga en cuenta que esto es puramente un estilo que usan algunas personas. No es obligatorio según el estándar ni es exigido por los compiladores
fuente
T t; int i = t.toInt();), entonces necesita una "clase real", y su código no se compilará si se suministraintparaT...classimplica que no solo esperas un "valor" que tal vez respalde a algunos operadores, copie o mueva la construcción y / o asignación, sino que específicamente necesitas un tipo que soporte alguna semántica de acceso de miembros. El vistazo más rápido a la declaración establece expectativas y desalienta, por ejemplo, el suministro de tipos integrados paraclassparámetros cuando eso ciertamente sería un error.Containeres en sí mismo una plantilla con dos parámetros de tipo.fuente
template<template<class U> class V> struct C {};Este fragmento es del libro de c ++. Aunque estoy seguro de que esto está mal.
Cada parámetro de tipo debe ir precedido de la clase de palabra clave o nombre de tipo:
Estas palabras clave tienen el mismo significado y se pueden usar indistintamente dentro de una lista de parámetros de plantilla. Una lista de parámetros de plantilla puede usar ambas palabras clave:
Puede parecer más intuitivo usar la palabra clave typename en lugar de class para designar un parámetro de tipo de plantilla. Después de todo, podemos usar tipos integrados (no de clase) como argumento de tipo de plantilla. Además, typename indica más claramente que el nombre que sigue es un nombre de tipo. Sin embargo, typename se agregó a C ++ después de que las plantillas ya estaban en uso generalizado; algunos programadores continúan usando la clase exclusivamente
fuente