Share via


Especificaciones de plantilla

La declaración template especifica un conjunto de clases o funciones con parámetros.

template < template-parameter-list > declaration

Comentarios

template-parameter-list es una lista separada por comas de parámetros de plantilla, que pueden ser tipos (con el formato class identifier, typename identifier o template < template-parameter-list > class identifier) o parámetros sin tipo que se usarán en el cuerpo de la plantilla. La sintaxis de un parámetro de plantilla es una de las siguientes:

parameter-declaration
class identifier [ = typename ] 
typename identifier [ = typename ]
template < template-parameter-list > class [identifier][= name]

Se pueden crear instancias de una plantilla de clase como para una clase normal, pero se deben incluir los argumentos de plantilla entre corchetes angulares (<>). Estos argumentos de plantilla pueden ser de cualquier tipo si la lista de argumentos de plantilla contiene la palabra clave class o typename, o un valor del tipo adecuado si se trata de un argumento sin tipo. No se requiere ninguna sintaxis especial para llamar a una plantilla de función, aunque los corchetes angulares y los argumentos de plantilla pueden ser necesarios si los parámetros de plantilla no se pueden deducir de los argumentos de la función.

template-parameter-list es una lista de parámetros utilizados por la función de plantilla que especifica qué partes del código siguiente variarán. Por ejemplo:

template< class T, int i > class MyStack...

En este caso, la plantilla puede recibir un tipo (class T) y un parámetro constante (int i). La plantilla utilizará el tipo T y el entero constante i durante la creación de instancias. Dentro del cuerpo de la declaración MyStack, debe hacer referencia al identificador T.

Una declaración de plantilla propiamente dicha no genera código; especifica una familia de clases o funciones, una o varias de las cuales se generarán cuando otro código haga referencia a ellas.

Las declaraciones de plantilla tienen ámbito global, de espacio de nombres o de clase. No se pueden declarar dentro de una función.

En el ejemplo siguiente se muestra la declaración, definición y creación de instancia de una plantilla de clase con un parámetro de tipo T y un parámetro de plantilla sin tipo i.

// template_specifications1.cpp
template <class T, int i> class TestClass 
{
public:
   char buffer[i];
   T testFunc(T* p1 );
};

template <class T, int i>
T TestClass<T,i>::testFunc(T* p1) 
{
    return *(p1++)
};

// To create an instance of TestClass
TestClass<char, 5> ClassInst;
int main()
{
}

Argumentos de plantilla sin tipo

Los parámetros de plantilla sin tipo deben ser de tipo entero, enumeración, puntero, referencia o puntero a miembro, y deben ser constantes en tiempo de compilación. Se pueden calificar como tipos const o volatile. No se permiten valores de punto flotante como parámetros de plantilla. No se permiten objetos de tipo class, struct o union como parámetros de plantilla sin tipo, aunque se permiten punteros a esos objetos. Las matrices que se pasan como parámetros de plantilla sin tipo se convierten en punteros. Las funciones que se pasan como parámetros sin tipo se tratan como punteros a función. No se permiten literales de cadena como parámetros de plantilla.

Usar typename en una declaración de plantilla

La palabra clave typename se puede utilizar en la lista de parámetros de plantilla. Las declaraciones de plantilla siguientes son idénticas:

template< class T1, class T2 > class X...
template< typename T1, typename T2 > class X...

Argumentos predeterminados para los parámetros de plantilla

Se pueden especificar argumentos predeterminados para las plantillas de clase mediante el signo = seguido del tipo o el valor predeterminado. Las plantillas de función no pueden tener argumentos predeterminados. Para obtener más información, vea Argumentos predeterminados para plantillas de clase.

template<typename Type> class allocator {};
template<typename Type, 
   typename Allocator = allocator<Type> > class stack 
{
};
stack<int> MyStack;

Reutilizar parámetros de plantilla

Los parámetros de plantilla se pueden reutilizar en la lista de parámetros de plantilla. Por ejemplo, se permite el código siguiente:

// template_specifications2.cpp

class Y 
{
};
template<class T, T* pT> class X1 
{
};
template<class T1, class T2 = T1> class X2 
{
};

Y aY;

X1<Y, &aY> x1;
X2<int> x2;

int main()
{
}

Plantillas como parámetros de plantilla

Los parámetros de plantilla pueden ser plantillas. Esta construcción significa que el argumento debe ser una plantilla, no una clase construida a partir de una plantilla. En el ejemplo siguiente, se puede omitir el nombre A del parámetro de plantilla, porque no se puede usar de ninguna manera.

// template_specifications3.cpp
#include <stdio.h>

template <class T> struct str1
{
   T t;
};

template <template<class A> class T> struct str2
{
    T<int> t;
};

int main()
{
    str2<str1> mystr2;
    mystr2.t.t = 5;
    printf_s("%d\n", mystr2.t.t);
}

Salida

5

Referencias como parámetros de plantilla

Visual Studio .NET 2003 introdujo la posibilidad de utilizar referencias como parámetros de plantilla sin tipo. Esto no se permitía en las versiones anteriores.

// references__supported_as_nontype_template_parameters.cpp
#include <stdio.h>

extern "C" int printf_s(const char*,...);
template <int & ri> struct S
{
   S()
   {
      printf_s("ri is %d\n", ri);
   }

   ~S()
   {
      printf_s("ri is %d\n", ri);
   }
};

int i = 1;

int main()
{
   S<i> s;
   i = 0;
}

Salida

ri is 1
ri is 0

Instancias de plantilla anidadas

En las versiones anteriores a Visual Studio 2005, había que insertar un espacio en blanco entre las listas de parámetros de plantilla al declarar instancias de plantilla anidadas. Ahora se permite la sintaxis siguiente:

// template_specifications4.cpp 

template <typename T> 
class A
{
};

template <int n> 
class B 
{
};

int main() 
{
   A<B<22>>();
}

Vea también

Referencia

Palabras clave de C++

Otros recursos

Plantillas