### Declaring and Defining Templates

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

#### Listing 1. 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, then define the function templates and the member functions of the class templates. Listing 3.10 shows you an example.

This source file is a template definition file, which you include 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 template arguments. Specifying these values is called instantiating the template. See Instantiating a Template.

#### Listing 2. 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, in your source file. Otherwise, the compiler generates an error saying that the function or class is undefined.

#### Providing declarations when declaring the template

Carbide.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. Listing 3.11 shows some examples.

##### Listing 3.11 Declarations in Template Declarations

// You must define names in a class template declaration

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