C++中的模板

Templates

 

定义一个模板使用的关键字:classtypename

在定义作为模板的时候:classtypename,作用是一样的


出处:http://www.cplusplus.com/doc/tutorial/templates/

函数模板

1 定义方式

template <class identifier> function_declaration;
template <typename identifier> function_declaration;


2 Example

 

template <class T>
T GetMax (T a, T b)
{
T result;

result = (a>b)? a : b;

return (result);
}


3 使用方法

function_name <type> (parameters);

例如:
int x,y;
GetMax <int> (x,y);


对于内部类型,通常是可以无需制定具体的类型,编译器会自动识别,

而是写成:

 

int x,y;

GetMax(x,y); //x,y为相同的类型


 

int x;

long y;

GetMax(x,y); //x,y为不相同的类型 报错 两种不同的内部类型

必须:

template <class T, class U>
T GetMin (T a, U b)
{
return (a<b?a:b);
}


int i,j;
long l;
i = GetMin<int,long> (j,l); //或者i = GetMin (j,l);

Class Template

通常是使用模板作为类成员变量的类型

1 Example:


template <class T>
class mypair
{
T values [2];
public:
mypair (T first, T second) //内联函数
{

values[0]=first; values[1]=second;
}
};

mypair<int> myobject (115, 36);               //这样使用
mypair<double> myfloats (3.0, 2.18);


2 成员函数为非内联函数


template <class T>
class mypair {
T a, b;
public:
mypair (T first, T second)
{a=first; b=second;}
T getmax ();
};

template <class T> //增加此声明
T mypair<T>::getmax ()

{
T retval;
retval = a>b? a : b;
return retval;
}

int main () {
mypair <int> myobject (100, 75);
cout << myobject.getmax();
return 0;
}

模板类成员函数外部定义方法:


template <class T>
T mypair<T>::getmax ()

模板特化 Template Specialization

1 将模板类转化为特定类型相关的类


// class template:
template <class T>

class mycontainer
{
T element;
public:
mycontainer (T arg) {element=arg;}
T increase () {return ++element;}
};

// class template specialization:
template <> //
class mycontainer <char> //将其特例化为char型
{

char element;
public:
mycontainer (char arg) {element=arg;}
char uppercase ()
{
if ((element>='a')&&(element<='z'))
element+='A'-'a';
return element;
}
};

int main () {
mycontainer<int> myint (7);
mycontainer<char> mychar ('j');
cout << myint.increase() << endl;
cout << mychar.uppercase() << endl;
return 0;
}

template <class T> class mycontainer { ... }; //模板类
template <> class mycontainer <char> { ... }; //特例化为char型
template <> class mycontainer <int> { ... }; //特例化为int型


模板来与之相应的特例化的类之间,并不是什么继承关系,

所以在特例化一个模板类时,需要将其所有的包含成员进行重写,可以进行扩展。

 

2 非模板类型参数 Non-type parameters for templates

 

template <class T, int N>             //int N
class mysequence

{
T memblock [N];
public:
void setmember (int x, T value);
T getmember (int x);
};

template <class T, int N>
void mysequence<T,N>::setmember (int x, T value)
{
memblock[x]=value;
}

template <class T, int N>
T mysequence<T,N>::getmember (int x)
{
return memblock[x];
}

int main () {
mysequence <int,5> myints;
mysequence <double,5> myfloats;
myints.setmember (0,100);
myfloats.setmember (3,3.1416);
cout << myints.getmember(0) << '\n';
cout << myfloats.getmember(3) << '\n';
return 0;
}


可以设置模板类型的缺省值:


template <class T=char, int N=10> class mysequence {..};

mysequence<> myseq; //可以缺省使用
mysequence<char,10> myseq; //等同于上面


 

四 Templates and multiple-file projects

  From the point of view of the compiler, templates are not normal functions or classes.

They are compiled on demand, meaning that the code of a template function is

not compiled until an instantiation with specific template arguments is required.

At that moment, when an instantiation is required, the compiler generates a function specifically

for those arguments from the template.

 

1 模板不会在代码编译的时候直接进行编译,而是在被实例化一个特定类型的模板时候,才会编译到,生成一个特定参数的函数。

When projects grow it is usual to split the code of a program in different source code files.

In these cases, the interface and implementation are generally separated.

Taking a library of functions as example, the interface generally consists of

declarations of the prototypes of all the functions that can be called.

These are generally declared in a "header file" with a .h extension,

and the implementation (the definition of these functions) is in an independent file with c++ code.
  
Because templates are compiled when required, this forces a restriction

for multi-file projects: the implementation (definition) of a template class

or function must be in the same file as its declaration.

That means that we cannot separate the interface in a separate header file,

and that we must include both interface and implementation in any file that uses the templates.


由于模板特殊的编译需要,模板类的定义和函数实现必须在同一个文件中进行。


Since no code is generated until a template is instantiated when required,

compilers are prepared to allow the inclusion more than once of the same

template file with both declarations and definitions in a project without generating linkage errors.


五 typename

定义一个模板使用的关键字:classtypename

在定义作为模板的时候:classtypename,作用是一样的。

使用typename,实际上也是为模板服务的,在某些情况下我们需要明确的指出某些变量为模板。

1 在一个模板类中使用另一个模板类定义一个变量时


template<typename T>
struct first
{
typedef T * pointer;
};
template<typename T>
class second
{
first<T>::pointer p; // syntax error (VC++中 并不报错)
};

 In a template, the name of a member of another class that depends on

its template parameter(s) (first<T>::pointer in this example, dependent

on the T parameter) is a dependent name that is not looked-up immediately.

To tell the compiler that it is meant to refer to a type and not some other sort of member,

you must add the keyword typename before it.

typename 能够在:依赖类型中,typename用来声明一个依赖于另一个模板类参数的嵌套类型。

posted @ 2011-12-01 22:13  __Shadow  阅读(593)  评论(0编辑  收藏  举报