Chapter Contents

Previous

Next
Templates

Template Declarations and Definitions

The syntax for declaring a class template is

template <class T> class C;  // T is a type parameter

Within the body of a class template or class template member definition, the class template name without a template argument list may be used as a synonym for the particular class specialization being instantiated. A specialization of a class template is referred to as a template class. For example:

template <class T> class C {
        C<T>* p1;
        C* p2;   // type is also C<T>*
        };

The SAS/C C++ Development System also supports the ANSI/ISO typename keyword. typename can be used as a substitute for the keyword class when declaring template type arguments, as follows:

template <typename T> class C;   // an alternate
                                 // declaration


Using Typename with Dependent Qualified Names

The primary use of typename is as a name modifier in template declarations. Dependent qualified names are defined as those names in which the qualifier scope explicitly depends on a template parameter that is part of the name. The typename keyword is required to precede dependent qualified names. This is necessary because declaration and expression parsing must be able to distinguish between type and nontype names before the types and values of the template arguments are known. Dependent qualified names cannot be resolved by lookup as they would be for a normal class of names.

For example, if T is a template parameter and A is a template class that has a single type parameter, then the names are referred to as dependent qualified names because the scopes of the names are dependent:

T::n
A<T>::n

In this example, the scope of the name is not dependent:

A<int>::n

An example of a template declaration that uses typename follows:

template <class T> class Vector {
        . . .
public:
   typedef T* Iterator;
   friend Iterator first( Vector<T>& );
   };
template <class T>
   typename Vector<T>::Iterator first( Vector<T>& v )
   { . . . };

The current release of the SAS/C C++ Development System only checks for typename when parsing declaration specifiers in a template declaration. However, the C++ draft requires the typename modifier on qualified dependent type names in the body of a template definition. You should consider using the typename keyword in new template code. For use with older compilers that do not support the typename keyword, the typename keyword can be hidden with the preprocessor directive as follows:

#define typename /* nothing */


Declaration Rules

Template classes and nonmember function templates may be declared multiple times in a translation unit, but they are subject to the single definition rule. The single definition rule states that a template may be defined at most once within each translation unit. However, a template may be defined in multiple translation units. Each specialization of a function or template class member must be defined in at most one translation unit.

Template class member declarations that are not friend declarations must be definitions.

Note:    Template friend declarations of template class members are not supported in this release of the SAS/C C++ Development System.  [cautionend]

Template declarations may be used to declare friend classes and functions. However, friend template declarations may not be definitions.

For each template declaration, the template parameters can be specified with different names just as different function parameter names may be specified in different function declarations. For example:

// forward declaration of template C
template <class T, class U> class C;

// redeclaration of template C
template <class X, class Y> class C;  

When declaring a template class member, the order of template parameters in the template class member must match the order of the corresponding parameters in the class template. The same order must also be used to specify the template parameters in the scope portion of the qualified member name being declared.

template <class T, class U>
class C {
public:
   static int i;
   static int j;
   };

template <class T, class U>
int C<T, U>::i = 0;   // OK

template <class T, class U>
int C<U, T>::j = 0;  // error - parameter order not
                     // the same

Note:    Beginning with Release 6.50, template parameters may not have default arguments.  [cautionend]


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.