谈一谈C++ template/C++ 模板
Posted xioacd99
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了谈一谈C++ template/C++ 模板相关的知识,希望对你有一定的参考价值。
这里劝退一波 Qt Ui,仅仅是 Ui,不是 Qt 哈
选择 Qt 一时爽, Ui 开发火葬场。
忙活两个小时,解决的只是一个非常小的窗口效果,接下来考验你的眼力的时间到了
你找到了上面两幅图的不同了吗?
文章目录
1 为什么要使用模板
也许平常写 C++ 的时候我们不用模板也能 6 得飞起,那为什么还会要产生模板的需求呢?
以下面的例子为例,如果我有了模板,我就可以生产同一类型的多个表情包
但是没有模板的你只能使用最原本的熊猫人,在斗图大战中败北,含恨而归
形象吧,接下来我们来谈一谈什么时候该使用模板,以及模板的语法和分类。
2 究竟我是否该使用模板
是否要用模板,我们可以借鉴开发时的 RunOfThree
原则
RunOfThree原则
第一次
用的时候写个“特例”
。第二次
用的时候copy
第一次的代码,第三次
用的时候就得写一个通用的,当然,为了达到通用
性,你要做的不仅仅是使用模板。
3 C++ 模板语法与分类
模板下面又分为函数模板
、类模板
、模板类
等等,这里我们简单地谈谈前面三种
3.1 函数模板
语法
template <class T1,class T2,...,>
返回类型 函数名(形参表)
statement;
例子
template <class T>
// equal to template <typename T>
T max(const T& a, const T& b)
return a > b ? a : b;
说明
template
是C++中用来声明模板的keyword,class和typename是模板形参的声明,两者的差别见:difference of keywords typename and class in templates- 并不是写了函数模板就可以自动处理所有类型的数据了,比如上面的max函数。如果你相对两个自定义类型对象使用,你还得自己重载运算符>。
3.2 类模板和模板类
虽然我们说模版类就是类模版实例化之后的类,但其实there is no such thing as a “template class,” there is only a “class template.”,见what is the difference between a template class and a class template
语法
template <class T>
class TestClass
function;
member;
;
例子
template <class T>
class TestClass
public:
void testFunction();
private:
T m_value; // 用个m_前缀方便将类成员变量和普通的区分开member
// 但是不要两种命名方法混用,就像这样
;
注:
-
类模板中的成员变量同样可以是int、double这种,可以类比到函数
-
类外定义成员函数需要多加一些东西
template <class T>
void TestClass<T>:: testFunction()
statement;
使用:我们所说的使用类模板就是利用模板生成一个具体的类,就像用摸具爸爸做出摸具儿子一样,然后我们再用摸具儿子就可以创建具体的对象来使用了。
3.3 模板的覆盖与特化
首先,来一个非常形象的解释
模板的覆盖和特化就像程序员给的小红伞,可以让特化后的类无视原来模板的规定,自行对相关情况进行处理。
3.3.1 模板的覆盖
和前面重载一样,如果类中出现有一个函数和模板中的参数原型一致,那么模板就会被覆盖(specifial first)
3.3.2 模板的特化
什么时候使用:写的模板能够处理大多数情况,数据只是小部分特例,重新写一个不划算。
分类
- 函数模板特化
// 原模板
template <typename T>
bool isZero(const T& a)
return a.value == 0;
// 特化
template <>
bool isZero<int>(const int& a)
return a == 0;
没有原模板就别谈特化了
- 类部分特化
template <typename T1,typename T2>
class TestClass
...
;
// 这里只需要写为进行特化的模板类型
template <typename T>
class SpecificalClass<T,int>
...
;
- 类全特化
template <typename T1,typename T2>
class TestClass
...
;
template <>
class SpecificalClass<int,int>
...
;
3.4 类模板与友元
3.4.1 按照定义的位置来分
- 封闭型
template <typename T>
class TestClass
// 函数体定义在模板体类,可以访问A任意实例的任意成员
friend void testFunction()
statement;
;
- 开放型
template <typename T>
class TestClass
template <typename T1>
friend void testFunction<T1>();
;
// 函数体定义在模板类外,友元可以访问A任意实例的任意成员
template <typename T>
void testFunction
statement;
- 特例型
template <typename T>
class TestClass
// 此时只有和类模板具有相同模板形参的友元函数才算是TestClass的友元
friend void testFunction<T>();
;
3.4.2 按照约束来分
-
模板类的非模板友元函数
-
不用模板的成员变量
template <typename T> class TestClass // 和普通的友元函数没什么差别 friend void testFunction() statement; ;
-
用~
template <typename T> class TestClass // 必须为每一个需要使用到的类型给出一个定义,属于overload friend void testFunction(TestClass<T>& obj); ; // 假设我的代码中只用到了int和double void testFunction(TestClas<int>& obj) statement; void testFunction(TestClas<double>& obj) statement;
-
模板类的约束类友元函数
每一个类的具体化都要有一个友元定义,有点像1.2,不过你需要在模板类前先声明友元函数
// 以这种形式 template<typename T>void testFunction();
-
模板类的非约束友元函数
有点像1.3
-
q imok aos hibu k aoz hex ie
以上是关于谈一谈C++ template/C++ 模板的主要内容,如果未能解决你的问题,请参考以下文章
C++模板类模板的全部特例化和局部特例化(偏特化-partial specialization)
C++ Primer 5th笔记(chap 16 模板和泛型编程)类模板部分特例化