目录
3.array和原生数组比较——array唯一优势:有越界检查


固定长度的顺序容器,就是定长数组
vector是动态开辟的,放在堆上的,且内部存的是指针;array就是个定长数组,放在栈上的,内部存的就是个数组

array相比原生数组唯一优势:有越界检查,因为有[]运算符重载,[]运算符重载中有assert检查。

array对比原生数组,还是有一些越界检查的优势的。但是实际中我们统一直接用vector更香!

整形int,char,unsigned int等。
1.浮点数、类对象以及字符串是不允许作为非类型模板参数的。
2.非类型的模板参数必须在编译期就能确认结果。
- template<class T>
- bool Less(T left, T right) //模板函数
- {
- return left < right;
- }
-
- 针对某些类型要特殊化处理
- template<>
- bool Less
(Date* left, Date* right) //模板特化 - {
- return *left < *right;
- }
-
- bool Less(Date* left, Date* right) //原生函数
- {
- return *left < *right;
- }
-
-
- 函数模板基本不用特化方式处理,直接写一个具体类型的函数更好、
- int main()
- {
- cout << Less(1, 2) << endl; // 可以比较,结果正确
-
- Date d1(2022, 7, 7);
- Date d2(2022, 7, 8);
- cout << Less(d1, d2) << endl; // 可以比较,结果正确
-
- Date* p1 = new Date(2022, 7, 16);
- Date* p2 = new Date(2022, 7, 15);
- cout << Less(p1, p2) << endl; // 可以比较,结果正确 3.
-
- return 0;
- }
正常的Less(d1, d2)比较日期类大小, 传进left < right后按照Date中的<运算符重载进行比较,但是Less(p1, p2)传的是指针,如果用模板函数会比较指针,所以这里用到模板特化函数去设置形参是Date*时比较*left < *right,类似于上面这种,就叫模板特化。当然也可以直接写出原生的函数,在没有原生函数的条件下,第3个Less(p1, p2)会优先调用模板特化函数,有原生函数会优先调用原生函数,在函数模板中是可以并存的,类模板中这样没法用。所以结论是:函数模板没必要特化,直接用原生函数就行
- template<class T1, class T2>
- class Data
- {
- public:
- Data() { cout << "Data
" << endl; } - private:
- T1 _d1;
- T2 _d2;
- };
-
- // 全特化 :全特化即是将模板参数列表中所有的参数都确定化
- template<>
- class Data<int, double>
- {
- public:
- Data() { cout << "Data
" << endl; } - };
-
- // 半特化/偏特化 1:
- // 1、将模板参数类表中的一部分参数特化。
- template<class T1>
- class Data
char> - {
- public:
- Data() { cout << "Data
" << endl; } - };
-
- // 半特化的写法2:
- // 2、偏特化并不仅仅是指特化部分参数,而是针对模板参数更进一步的条件限制所设计出来
- //的一个特化版本。
- template<class T1, class T2>
- class Data
- {
- public:
- Data() { cout << "Data
" << endl; } - };
-
- // 半特化的写法3:
- template<class T1, class T2>
- class Data
- {
- public:
- Data() { cout << "Data
" << endl; } - };
-
- int main()
- {
- Data<int, int> d1;
- Data<int, double> d2;
- Data<int, char> d3;
- Data<char, char> d4;
- Data<int*, int*> d5;
- Data<int*, char*> d6;
- Data<int*, string*> d7;
- Data<int*, void*> d8;
- Data<int*, int> d9;
- Data<int&, char&> d10;
-
- return 0;
- }

- #include
- #include
-
- template<class T>
- struct Less //模板函数
- {
- bool operator()(const T& x, const T& y) const
- {
- return x < y;
- }
- };
-
- //template<> 这样写只能传Date*,所以不如干脆写个偏特化可以传任何指针类型
- //struct Less
- //{
- // bool operator()(Date* x, Date* y) const
- // {
- // return *x < *y;
- // }
- //};
-
- // 偏特化
- template<class T> //模板偏特化函数
- struct Less
- {
- bool operator()(T* x, T* y) const
- {
- return *x < *y;
- }
- };
-
- int main()
- {
- Date d1(2022, 7, 7);
- Date d2(2022, 7, 6);
- Date d3(2022, 7, 8);
-
- vector
v1; - v1.push_back(d1);
- v1.push_back(d2);
- v1.push_back(d3);
- // 可以直接排序,结果是日期升序
- sort(v1.begin(), v1.end(), Less
()); -
- vector
v2; - v2.push_back(&d1);
- v2.push_back(&d2);
- v2.push_back(&d3);
-
- // 可以直接排序,结果错误日期还不是升序,而v2中放的地址是升序
- // 此处需要在排序过程中,让sort比较v2中存放地址指向的日期对象
- // 但是走Less模板,sort在排序时实际比较的是v2中指针的地址,因此无法达到预期
- sort(v2.begin(), v2.end(), Less
()); -
- vector<int*> v3;
- v3.push_back(new int(3));
- v3.push_back(new int(1));
- v3.push_back(new int(2));
- sort(v3.begin(), v3.end(), Less<int*>());
-
- return 0;
- }
v1使用模板函数,v2,v3使用模板偏特化函数。