Especificações de modelo

A declaração de template especifica um conjunto de classes ou funções parametrizadas.

template < template-parameter-list > declaration

Comentários

A lista de parâmetros de modelo é uma lista separada por vírgulas de parâmetros de modelo que podem ser parâmetros com (na forma class identifier, typename identifier ou template < template-parameter-list > class identifier) ou sem tipos a serem usados no corpo do modelo. A sintaxe de um parâmetro de modelo é uma destas:

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

Você pode instanciar um modelo de classe assim como instanciaria uma classe normal, mas deve incluir os argumentos do modelo entre parênteses (<>). Esses argumentos de modelo poderão ser de qualquer tipo, se a lista de argumentos de modelo contiver a classe ou a palavra-chave typename ou um valor do tipo apropriado, se o argumento não for de tipo. Nenhuma sintaxe especial é necessária para chamar um modelo de função, embora os parâmetros e os argumentos de modelo possam ser necessários se os parâmetros de modelo não puderem ser deduzidos dos argumentos da função.

A lista de parâmetros de modelo é uma lista de parâmetros usados pela função de modelo que especifica quais partes do código a seguir variarão. Por exemplo:

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

Nesse caso, o modelo pode receber um tipo (class T) e um parâmetro constante (int i). O modelo usará o tipo T e o inteiro constante i na instanciação. No corpo da declaração MyStack, você deve se referir ao identificador T.

Uma declaração de modelo em si não gerencia o código, ela especifica uma família de classes ou de funções, e uma ou mais delas serão geradas quando referenciadas por outro código.

As declarações de modelo têm escopo global, de namespace ou de classe. Elas não podem ser declaradas em uma função.

O exemplo a seguir ilustra a declaração, a definição e a instanciação de um modelo de classe com um parâmetro de tipo T e um parâmetro de modelo sem 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 modelo sem tipo

Os parâmetros de modelo sem tipo devem ser do tipo integral, enumeration, pointer, reference or pointer to member e ser constantes no tempo de compilação. Eles podem ser qualificados como tipos const ou volatile. Valores de ponto flutuante não são permitidos como parâmetros de modelo. Os objetos do tipo class, struct ou union não são permitidos como parâmetros de modelo sem tipo, embora os ponteiros para esses objetos sejam permitidos. As matrizes transmitidas como parâmetros de modelo sem tipo são convertidas em ponteiros. As funções transmitidas como parâmetros sem tipo são tratadas como ponteiros de função. Literais de cadeia de caracteres não são permitidos como parâmetros de modelo.

Usando typename em uma declaração de modelo

A palavra-chave typename pode ser usada na lista de parâmetros de modelo. As seguintes declarações de modelo são idênticas:

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

Argumentos padrão para parâmetros de modelo

Os modelos de classe podem ter argumentos padrão especificados com o sinal de = seguido do tipo padrão ou do valor. Os modelos de função não podem ter argumentos padrão. Para obter mais informações, consulte Argumentos padrão para modelos de classe:

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

Reutilização de parâmetros de modelo

Os parâmetros de modelo podem ser reutilizados na lista de parâmetros de modelo. Por exemplo, o código a seguir é permitido:

// 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()
{
}

Modelos como parâmetros de modelo

Os parâmetros de modelo podem ser modelos. Essa construção significa que o argumento deve por si só ser um modelo, não uma classe construída a partir do modelo. No exemplo a seguir, o nome A do parâmetro de modelo para um parâmetro de modelo pode ser omitido, pois ele não pode ser usado.

// 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);
}

x5w1yety.collapse_all(pt-br,VS.140).gifSaída

5

Referências como parâmetros de modelo

O Visual Studio .NET 2003 introduziu a capacidade de usar referências como parâmetros de modelo sem tipo. Isso não foi permitido em versões 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;
}

x5w1yety.collapse_all(pt-br,VS.140).gifSaída

ri is 1
ri is 0

Instâncias de modelo aninhadas

As versões do Visual Studio antes do Visual Studio 2005 exigiam que o espaço em branco fosse inserido entre as listas de parâmetros de modelo quando as instâncias aninhadas de modelo fossem declaradas. A sintaxe a seguir agora é permitida:

// template_specifications4.cpp 

template <typename T> 
class A
{
};

template <int n> 
class B 
{
};

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

Consulte também

Referência

Palavras-chave C++

Outros recursos

Modelos