[ First ]  [ Previous ]  [ Next ]  [ Last ]  [ Manuals ]


Declaring and Defining Templates

In a header file, declare your class functions and function templates, as shown in Listing 4.8.

templ.h: A Template Declaration File:
template <class T> 
class Templ {
  T  member;
public:
  Templ(T x) { member=x; }
  T  Get();
};
  
template <class T> 
T Max(T,T);

In a source file, include the header file and define the function templates and the member functions of the class templates. Listing 4.9 shows you an example.

This source file is a template definition file. You'll include this file in any file that uses your templates. You do not need to add the template definition file to your project. Although this is technically a source file, you work with it as if it were a header file.

The template definition file does not generate code. The compiler cannot generate code for a template until you specify what values it should substitute for the templates arguments. Specifying these values is called instantiating the template. See "Instantiating a Template."

templ.cp: A Template Definition File:
#include "templ.h"
  
template <class T> 
T Templ<T>::Get() 
{ 
  return member; 
}
  
template <class T> 
T Max(T x, T y) 
{ 
  return ((x>y)?x:y); 
}


WARNING!

Do not include the original template declaration file, which ends in .h. If you include the template .h file in your source file, the compiler will generate an error saying that the function or class is undefined.

Providing declarations when declaring the template

CodeWarrior C++ processes any declarations in a template when the template is declared, not when it is instantiated.

Although the C++ compiler currently accepts declarations in templates that are not available when the template is declared, future versions of the compiler will not. shows some examples.

Declarations in template declarations:
// Names in a class template declaration have to be defined

template<typename T> struct foo {
  bar *member;  // illegal (but currently accepted)
};
struct bar { };
foo<int> fi;	

// Workaround: Declare all names before using them:

struct bar;
template<typename T> struct foo {
  bar *member;  // OK
};
struct bar { };
foo<int> fi;	


// Names in template argument dependent base classes:

template<typename T> struct foo {
   typedef T *tptr;
};
template<typename T> struct bar : foo<T> {
   tptr member;  // illegal (but currently accepted)
};

// Workaround: Use qualifed name syntax:

template<typename T> struct foo {
  typedef T *tptr;
};
template<typename T> struct bar : foo<T> {
  typename foo<T>::tptr member;  // OK
};


// The correct usage of typename in template argument 
// dependent qualified names in some contexts:

template<class T> struct X {
   typedef X *xptr;
   xptr f();
};
template<class T> X<T>::xptr X<T>::f() // 'typename' missing
{
   return 0;
}

// Workaround: Use 'typename':

template<class T> typename X<T>::xptr X<T>::f() // OK
{
  return 0;
} 


[ First ]  [ Previous ]  [ Next ]  [ Last ]  [ Manuals ]

Visit the Metrowerks website at: http://www.metrowerks.com
For assistance contact Metrowerks Technical Support at: cw_support@metrowerks.com
Copyright © 2000, Metrowerks Corp. All rights reserved.

Last updated: August 17, 2000