Al declarar una plantilla, estoy acostumbrado a tener este tipo de código:
template <class T>
Pero en esta pregunta , usaron:
template <unsigned int N>
Verifiqué que se compila. Pero, ¿qué significa? ¿Es un parámetro que no es de tipo? Y si es así, ¿cómo podemos tener una plantilla sin ningún parámetro de tipo?
static constexpr int
lugar de suenum
. Entonces laFactorial<0>
plantilla tendríastatic constexpr int value = 1
, ytemplate <int N> struct Factorial
puede tenerstatic constexpr int value = N * Factorial<N - 1>::value;
constexpr
.Sí, es un parámetro que no es de tipo. Puede tener varios tipos de parámetros de plantilla
Lo que tienes ahí es del último tipo. Es una constante de tiempo de compilación (la denominada expresión constante) y es de tipo entero o enumeración. Después de buscarlo en el estándar, tuve que mover las plantillas de clase a la sección de tipos, aunque las plantillas no son tipos. Pero se les llama parámetros de tipo con el propósito de describir esos tipos de todos modos. Puede tener punteros (y también punteros a miembros) y referencias a objetos / funciones que tienen vínculos externos (aquellos a los que se pueden vincular desde otros archivos de objeto y cuya dirección es única en todo el programa). Ejemplos:
Parámetro de tipo de plantilla:
Parámetro de número entero de plantilla:
Parámetro de puntero de plantilla (pasar un puntero a una función)
Parámetro de referencia de plantilla (pasando un número entero)
Parámetro de plantilla de plantilla.
No es posible una plantilla sin parámetros. Pero una plantilla sin ningún argumento explícito es posible, tiene argumentos predeterminados:
Sintácticamente,
template<>
está reservado para marcar una especialización de plantilla explícita, en lugar de una plantilla sin parámetros:fuente
SillyExample
no puede ser compilado por GCC 4.8.4. El primer error esthe value of ‘flag’ is not usable in a constant expression
. También hay otros erroresUsted modela su clase basándose en un 'int sin firmar'.
Ejemplo:
fuente
Una clase de plantilla es como una macro, solo que mucho menos malvada.
Piense en una plantilla como una macro. Los parámetros de la plantilla se sustituyen en una definición de clase (o función), cuando define una clase (o función) utilizando una plantilla.
La diferencia es que los parámetros tienen "tipos" y los valores pasados se verifican durante la compilación, como los parámetros de las funciones. Los tipos válidos son los tipos habituales de C ++, como int y char. Cuando crea una instancia de una clase de plantilla, pasa un valor del tipo que especificó y, en una nueva copia de la definición de la clase de plantilla, este valor se sustituye en el lugar donde estaba el nombre del parámetro en la definición original. Como una macro.
También puede utilizar "
class
" o "typename
tipos " para los parámetros (en realidad, son los mismos). Con un parámetro de uno de estos tipos, puede pasar un nombre de tipo en lugar de un valor. Al igual que antes, en todas partes el nombre del parámetro estaba en la definición de la clase de plantilla, tan pronto como crea una nueva instancia, se convierte en el tipo que pase. Este es el uso más común de una clase de plantilla; Todo el que sepa algo sobre las plantillas de C ++ sabe cómo hacer esto.Considere este código de ejemplo de clase de plantilla:
Funcionalmente es lo mismo que este código de uso de macros:
Por supuesto, la versión de plantilla es mil millones de veces más segura y flexible.
fuente