template<class T> class Array {
T* v;
int sz;
public:
explicit Array(int);
T& operator[](int);
T& elem(int i) { return v[i]; }
};
The prefix template<class T>
specifies that a template is being declared and that a
type-name
T
may be used in the declaration.
template<class T1, class T2> struct A {
void f1();
void f2();
};
template<class T2, class T1> void A<T2,T1>::f1() { } // OK
template<class T2, class T1> void A<T1,T2>::f2() { } // error
template<class ... Types> struct B {
void f3();
void f4();
};
template<class ... Types> void B<Types ...>::f3() { } // OK
template<class ... Types> void B<Types>::f4() { } // error
— end example
template<class T> class Array {
T* v;
int sz;
public:
explicit Array(int);
T& operator[](int);
T& elem(int i) { return v[i]; }
};
template<class T> T& Array<T>::operator[](int i) {
if (i<0 || sz<=i) error("Array: range error");
return v[i];
} — end exampleArray<int> v1(20); Array<dcomplex> v2(30); v1[3] = 7; // Array<int>::operator[]() v2[3] = dcomplex(7,8); // Array<dcomplex>::operator[]()— end example
template<class T> struct A {
class B;
};
A<int>::B* b1; // OK: requires A to be defined but not A::B
template<class T> class A<T>::B { };
A<int>::B b2; // OK: requires A::B to be defined
— end note
template<class T> class X {
static T s;
};
template<class T> T X<T>::s = 0;
struct limits {
template<class T>
static const T min; // declaration
};
template<class T>
const T limits::min = { }; // definition
— end example
template <class T> struct A {
static int i[];
};
template <class T> int A<T>::i[4]; // 4 elements
template <> int A<int>::i[] = { 1 }; // OK: 1 element
— end example