In a header file, declare your class functions and function templates, as shown in Listing 3.9.
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.
#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.
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.
// 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;
}