您的位置:首页 > Web前端

February 16th Monday 2009 (二月 十六日 月曜日)

2009-02-26 11:26 537 查看
Template Specializations

Implicit Instantiations

ArrayTb<int, 100> stuff; // implicit instantiation

The compiler doesn't generate an implicit instantiation of the class until it needs an object:

ArrayTb<double, 30> * pt; // a pointer, no object needed yet
pt = new ArrayTb<double, 30>; // now an object is needed

Explicit Instantiations

The compiler generates an explicit instantiation of a class declaration when you declare a class using the
keyword template and indicating the desired type or types. The declaration should be in the same namespace as
the template definition. For example, the declaration

template class ArrayTb<String, 100>; // generate ArrayTB<String, 100> class

In this case the compiler generates the class definition, including method definitions, even though no object
of the class has yet been created or mentioned. Just as with the implicit instantiation, the general template is
used as a guide to generate the specialization.

Explicit Specializations

A specialized class template definition has the following form:

template <> class Classname<specialized-type-name> { ... };

template <> class SortedArray<char *>
{
...// details omitted
};

SortedArray<int> scores; // use general definition
SortedArray<char *> dates; // use specialized definition

Partial Specializations

// general template
template <class T1, class T2> class Pair {...};
// specialization with T2 set to int
template <class T1> class Pair<T1, int> {...};
// specialization with T1 and T2 set to int
template <> class Pair<int, int> {...};

Pair<double, double> p1; // use general Pair template
Pair<double, int> p2; // use Pair<T1, int> partial specialization
Pair<int, int> p3; // use Pair<int, int> explicit specialization

// general template
template <class T1, class T2, class T3> class Trio{...};
// specialization with T3 set to T2
template <class T1, class T2> class Trio<T1, T2, T2> {...};
// specialization with T3 and T2 set to T1*
template <class T1> class Trio<T1, T1*, T1*> {...};

Trio<int, short, char *> t1; // use general template
Trio<int, short> t2; // use Trio<T1, T2, T2>
Trio<char, char *, char *> t3; use Trio<T1, T1*, T1*>

Member Templates

// tempmemb.cpp -- template members
#include <iostream>
using namespace std;

template <typename T>
class beta
{
private:
template <typename V> // nested template class member
class hold
{
private:
V val;
public:
hold(V v = 0) : val(v) {}
void show() const { cout << val << endl; }
V Value() const { return val; }
};
hold<T> q; // template object
hold<int> n; // template object
public:
beta( T t, int i) : q(t), n(i) {}
template<typename U> // template method
U blab(U u, T t) { return (n.Value() + q.Value()) * u / t; }
void Show() const {q.show(); n.show();}
};
int main()
{
beta<double> guy(3.5, 3);

guy.Show();
cout << guy.blab(10, 2.3) << endl;
cout << "Done/n";
return 0;
}

Or another way define a memeber template.

template <typename T>
class beta
{
private:
template <typename V> // declaration
class hold;
hold<T> q;
hold<int> n;
public:
beta( T t, int i) : q(t), n(i) {}
template<typename U> // declaration
U blab(U u, T t);
void Show() const {q.show(); n.show();}
};
// member definition
template <typename T>
template<typename V>
class beta<T>::hold
{
private:
V val;
public:
hold(V v = 0) : val(v) {}
void show() const { cout << val << endl; }
V Value() const { return val; }
};

// member definition
template <typename T>
template <typename U>
U beta<T>::blab(U u, T t)
{
return (n.Value() + q.Value()) * u / t;
}

The definitions have to identify T, V, and U as template parameters. Because the templates are nested, you have
to use the

template <typename T>
template <typename V>

syntax instead of the

template<typename T, typename V>

syntax.

Templates As Parameters

// tempparm.cpp -- template template parameters
#include <iostream>
using namespace std;
#include "stacktp.h"

template <template <typename T> class Thing>
class Crab
{
private:
Thing<int> s1;
Thing<double> s2;
public:
Crab() {};
// assumes the thing class has push() and pop() members
bool push(int a, double x) { return s1.push(a) && s2.push(x); }
bool pop(int & a, double & x){ return s1.pop(a) && s2.pop(x); }
};

int main()
{
Crab<Stack> nebula;
// Stack must match template <typename T> class thing
int ni;
double nb;

while (cin>> ni >> nb && ni > 0 && nb > 0)
{
if (!nebula.push(ni, nb))
break;
}

while (nebula.pop(ni, nb))
cout << ni << ", " << nb << endl;
cout << "Done./n";

return 0;
}

The Thing<int> is instantiated as Stack<int> and Thing<double> is instantiated as Stack<double>. In short,
the template parameter Thing is replaced by whatever template type is used as a template argument in declaring
a Crab object.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: