c++中程序员使用模板能够写出与类型无关的代码,提高源代码重用,使用合适,大大提高了开发效率。此前,可以使用宏实现模板的功能,但是模板更加安全、清晰。在编写模板相关的代码是我们用到两个关键词:template和class(或者typename),class和typename基本没有区别。
1、函数模板
函数模板本质上就是实现针对不同类型的同一种算法的代码,其基本用法可以是形如:
template
ReturnValue function(Argments)
{
// code
}
这里template
1 template <class T> T foo(T& lhs,T& rhs)
2 {
3 T tmp = lhs;
4 lhs = rhs;
5 rhs = tmp;
6 return lhs>rhs?lhs:rhs;
7 }
8
9 int main()
10 {
11 int a(5),b(10);
12 cout << foo(a,b) << endl;
13 cout << "a=" << a << endl;
14 cout << "b=" << b << endl;
15
16 string c("hello"),d("world");
17 cout << foo(c,d) << endl;
18 cout << "c=" << c << endl;
19 cout << "d=" << d << endl;
20 }
1-5行就是函数模板的基本使用方式,foo()函数的功能是交换两个参数,然后返回较大的值,但是foo()函数并不关心参数的类型 。当我们在main()中使用foo模板是,分别使用int和string类型都能得到期望的结果,而foo的代码只写了一份,没有针对int和string。
这是输出结果:
10
a=10
b=5
world
c=world
d=hello
2、类中的函数模板
类中含有成员函数模板的情况和上一种情况类似,只是限定了一下作用域。说实话,这一种情况应该比上一种情况更加常见,因为c++是一门面向对象的语言,我们定义的函数,通常需要定义在类中,尽量减少全局函数的使用。当然有点扯远了,写个小例子,说明用法:
class X
{
public:
template <class T> void mf(T* t) {}
};
int main()
{
int i;
X* x = new X();
x->mf(&i);
}
基本和第一种情况一样,不再赘述了。
3、简单的类模板
定义类模板的语法通项可以是这样的公式:
template
class CLASSNAME
{
//members.
};
template
ReturnValue CLASSNAME
{
//code.
}
类模板的使用大体和函数模板类似,只是要注意一点,当声明和定义相分离时,定义成员函数的时候,光限定模板名是不够的,要加上类型,只有这样限定才会是一个类名而非模板。举个例子:
template <class T>
class Bar {
void foo();
};
template<class t>
void Bar<T>::foo()
{
//
}
void Bar
4、类模板中的函数模板
类中的成员函数也可以是一个模板,这样就形成了一种层次关系。需要注意的是,在定义成员函数函数模板的时候需要在上例的基础上,考虑模板间的层次关系。例如这样一段代码:
1 template<typename T>
2 class X
3 {
4 public:
5 template<typename U>
6 void mf(const U &u);
7 };
8
9 template<typename T>
10 template <typename U>
11 void X<T>::mf(const U &u)
12 {
13 }
14
15 int main()
16 {
17 }
9-10行中限定了两个类型参数T、U的层次,其中U是成员函数函数模板的类型参数,如果11行这样写:
void X<U>::mf(const T &u)
就会报错。
还有一点需要注意的是:
Member template functions cannot be virtual functions and cannot override virtual functions from a base class when they are declared with the same name as a base class virtual function.
当使用与基类虚函数相同的名称进行声明时,成员模板函数不能是虚函数并且不能从基类重写虚函数。
关于之间的区别还是写两段代码具体的感受一下比较好。
5、在普通类中嵌套类模板
嵌套类模板被声明为外部类范围内的类模板,可以在封闭类的内部或外部定义它们。通俗点说就是嵌套类模板的作用范围是它所在类的里边,嵌套类的定义可以在外边定义。,如下是一段msdn上面的嵌套类的简单例子:
1 #include <iostream>
2 using namespace std;
3
4 class X
5 {
6
7 template <class T>
8 struct Y
9 {
10 T m_t;
11 Y(T t): m_t(t) { }
12 };
13
14 Y<int> yInt;
15 Y<char> yChar;
16
17 public:
18 X(int i, char c) : yInt(i), yChar(c) { }
19 void print()
20 {
21 cout << yInt.m_t << " " << yChar.m_t << endl;
22 }
23 };
24
25 int main()
26 {
27 X x(1, 'a');
28 x.print();
29 }
struct Y就是嵌套在class X中的一个类模板,在X类中模板Y实例化出了2个类型实例,分别是Y
6、在类模板中嵌套类模板
与上一种情况类似,只是这次外层类是一个类模板,而非具体的类类型。这种情况下最值得注意的就是:
When nested class templates are defined outside of their enclosing class, they must be prefaced by the template parameters for both the class template (if they are members of a class template) and template parameters for the member template.
当嵌套类模板在其封闭类的外部定义时,它们必须以类模板(如果它们是类模板的成员)的模板参数和成员模板的模板参数开头。------MSDN手册
翻译的也是比较拗口,但是读几遍的话也很好理解:当定义嵌套类时我们需要考虑的是,也就是第3中情况提到的需要注意的情况,”::“域作用符是作用于类上的,而非模板上的。所以如果在外部定义嵌套类时,首先我们不仅要在外层类模板后带上模板参数,使其形式上(还没有实例化)成为一个类,嵌套类也需要加上模板参数,使其形式上成为一个类。
1 #include <iostream>
2 using namespace std;
3
4 template <class T>
5 class X
6 {
7 template <class U> class Y
8 {
9 U* u;
10 public:
11 Y();
12 U& Value();
13 void print();
14 ~Y();
15 };
16
17 Y<int> y;
18 public:
19 X(T t) { y.Value() = t; }
20 void print() { y.print(); }
21 };
22
23 template <class T>
24 template <class U>
25 X<T>::Y<U>::Y()
26 {
27 cout << "X<T>::Y<U>::Y()" << endl;
28 u = new U();
29 }
30
31 template <class T>
32 template <class U>
33 U& X<T>::Y<U>::Value()
34 {
35 return *u;
36 }
37
38 template <class T>
39 template <class U>
40 void X<T>::Y<U>::print()
41 {
42 cout << this->Value() << endl;
43 }
44
45 template <class T>
46 template <class U>
47 X<T>::Y<U>::~Y()
48 {
49 cout << "X<T>::Y<U>::~Y()" << endl;
50 delete u;
51 }
52
53 int main()
54 {
55 X<int>* xi = new X<int>(10);
56 X<char>* xc = new X<char>('c');
57 xi->print();
58 xc->print();
59 delete xi;
60 delete xc;
61 }
最后还值得注意的是,正如第四种情况那样,嵌套类与外层类的模板参数也有层次关系。通常写成两行:
template
template
T被当成外层类的模板参数,U被当成嵌套类的模板参数。我看有的书上便于区分会写成缩进的形式:
template
template
关于模板的知识多,暂时没精力写了,明天再接着写下去。有哪些地方不到位的,还请各位看官指正,谢谢。本人QQ:5435620.EMAIL:baixiangcpp@gmail.com。
原文链接: https://www.cnblogs.com/ittinybird/p/4667510.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/219454
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!