Template Specifications
The document is archived and information here might be outdated

Template Specifications

The template declaration specifies a set of parameterized classes or functions.

Grammar

template-declaration :
template < template-argument-list > declaration
template-argument-list :
template-argument
template-argument-list , template-argument
template-argument :
type-argument
argument-declaration
type-argument :
class identifier
typename identifier

The template declaration specifies a set of parameterized classes or functions.

The template-argument-list is a comma-separated list of types (in the form class identifier, typename identifier, or template type) or a non-type to be used in the template body. The declaration field must be a declaration of a function or class.

You can instantiate a class template much like you would instantiate a normal class, but you must include the template arguments within angle brackets. No special syntax is required to call a function template.

With function templates, each template-argument must appear at least once in the template-argument-list of the function being declared.

The template-argument-list is a list of arguments used by the template function that specifies which parts of the following code will vary. For example:

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

In this case the template can receive a type (class T) and a constant parameter (int i). The template will use type T and the constant integer i upon construction. Within the body of the MyStack declaration, you must refer to the T identifier.

Examples

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

The following example shows how to pass a parameter to a template:

// template_specifications2.cpp
template<typename T>
class X
{
};

template<template<typename U> class T1, typename T2>
class Y
{
};

Y<X, int> aY;

int main()
{
}

The typename keyword can be used in the template-argument-list. The following template declarations are identical:

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

Template arguments of the following form are allowed:

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

Visual C++ supports the reuse of template parameters in the template parameter list. For example, the following code is now legal:

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

A template declaration itself does not generate code; it specifies a family of classes or functions, one or more of which will be generated when referenced by other code.

Template declarations have global or namespace scope.

Visual C++ performs syntax checking of template definitions. Visual C++ 5.0 and later can detect errors that previous versions cannot. The compiler can now detect syntax errors of templates that are defined but never instantiated.

Here is a list of common errors which could compile with the Visual C++ 4.0 compiler, but not with Visual C++ 5.0 or later:

  • A user-defined type is used in a template declaration before it is declared, but it is declared before the first instantiation or use of the template. For example:
    template<class T> class X {
       //...
       Data m_data;   // Error Visual C++ 5.0 or later, Data not defined
    };
    
    class Data {
    };
    
    void g() { X<int> x1; }
    

Move the declaration of Data before the class template X to fix this problem.

  • A member function is declared outside a class template, whereas it is never declared inside the class. For example:
    template<class T> class X {
       //no mf declared here
    };
    
    //This definition did not cause an error with Visual 
    //C++ 4.0, but it will cause an error with Visual 
    //C++ 5.0 or later
    //
    template<class T> void X<T>::mf() {...};
    
  • A class identifier is considered to be a normal class unless declared to be a class template. For example, the following code generates an error with Visual C++ 5.0 or later but not with Visual C++ 4.0:
    template<class T> class X {
       friend class Y<T>;   //Parsed as Y 'less-than' //T 'greater-than';
       Z<T> mf( );            //Parsed as Z 'less-than' T 'greater-than';
    };
    
    template<class T> class Y {...};
    template<class T> class Z {...};
    
    X<int> x;
    

To fix the problem, forward declare Y and Z before the definition of X.

template<class T> class Y {...};
template<class T> class Z {...};

template<class T> class X {...};

In Visual C++ .NET, it is now possible to use template parameters:

// template_specifications4.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("%d\n", mystr2.t.t);
}

Output

5

See Also

Templates | C++ Keywords

Show:
© 2016 Microsoft