《STL源码剖析》学习-- 1.9-- 可能令你困惑的C++语法1
最近在看侯捷的《STL源码剖析》,虽然感觉自己c++看得比较深一点,还是感觉还多东西不是那么明白,这里将一些细小的东西或者概念记录一下。
有些东西是根据《C++编程思想》理解的,记录一下加深印象。
STL没有太多的OO(object oriented),基本思想是GP(Generic Programming)。模板是泛型编程最基础的东西。
这里主要针对1.9节 可能令你困惑的C++语法 所列出来的组态进行讲解,因为书上基本没什么讲解。
1、模板 template
1.1 默认模板参数
很简单的类似于函数的默认参数,只要在后面加等于具体的类名即可以了。
如:template<class T, class U = char> void f() { T a; U b; };
1.2 typename:
如果在用模板定义的函数内如果不用typename标出类名,则只能把标示符当做类的静态成员,可以访问,但却不能新建类型,
如下代码:id为嵌套的类型。此时typename的作用是通知编译器,被限定的标示符为一个类型。
template<typename T>
class M{//typename T::id i;T::id i;
public:void f(){ i.g();}
};class X{
public:class id{public:void g(){cout <<"x" <<endl;};};
};
当没有typename时,无法定义i,但是我用函数时确实可以的,如下:
template<typename T>
void func(){T::id i;i.g();
}
int main(){func<X>();system("pause");}
可能是不同编译器的原因,为了程序稳定性,模板编程过程中还是最好用typename。
1.3 模板类型推断
在实例化类模板时,总是需要使用尖括号并且提供所有的非默认模板参数;然而在实例化函数模板时,经常可以省略模板参数。
如:
template< typename T> const T& min(const T& a, const T& b){return (a<b)? a:b;}
可以通过加尖括号来调用,也可以不,让编译器从函数的参数中推断出模板的类型,这就是类型推断。
如调用min可以如下:
int i,j;int z= min(i,j);
但此时i,j类型必须完全一致,如果不一致,即使可以进行类型转换(如int 和 float),但是编译器依然会报错,此时必须明确指出模板类型。
1.4 偏特化
一般的往往将偏特化理解为给定模板中的部分模板参数以具体的类,余下的泛化。其实不然,在本书3.4节traits编程技法一节,提到,“所谓partial specialization 的意思是提供另一份template的定义式,而其本身仍为templatized。”,“针对(任何)template参数更进一步的条件限制所设计出来的一个特化版本”。
全特化就是所有的模板都为具体的类。
T* 特化允许用指针类型匹配的模式(也只能匹配指针类型),const T* 特化允许使用指向const的指针 类型匹配(也只能匹配指向const的指针)。
注意,类模板可以偏特化,而函数模板不可以偏特化,即函数名后不可以加<>,但是可以通过重载达到类似偏特化的效果。
当有好多个版本的函数符合模板函数规则时,为了避免二义性,编译器总是选择特化程度最高的的模板。
如 template<class T,class U> void f() { T a; U b; };
某个特化版本为 template<> void f<int,char>() { int a; char b; };
某个偏特化版本为 template<class U> void f<int,U>() { int a; U b; };
1.5模板和友元(主要是限定友元)bound friend templates
class template 的某个具体实现与friend function template的某个具体实现有一对一的关系。
友元函数模板必须提前声明,本书中写到GCC中不需要前置声明。
如下,f()为Friendly类的友元函数,都为模板。此例中两者都是int的示例,注意Friendly中的f的声明里尖括号(或者<T>,不写也很容易推断),诉编译器f是一个模板,而不是普通函数,否则编译器就会找普通函数而找不到。
template<class T> class Friendly;
template<class T> void f(const Friendly<T>&);template<class T>
class Friendly{T t;
public:Friendly(const T& theT):t(theT){}friend void f<>(const Friendly<T>&);void g(){f(*this);}
};template<class T>
void f(const Friendly<T>& fo){cout << fo.t << endl;
}
void h(){f(Friendly<int>(1));
}int main(){h();Friendly<int>(2).g();
}
《STL源码剖析》学习-- 1.9-- 可能令你困惑的C++语法1相关推荐
- STL源码剖析学习七:stack和queue
STL源码剖析学习七:stack和queue stack是一种先进后出的数据结构,只有一个出口. 允许新增.删除.获取最顶端的元素,没有任何办法可以存取其他元素,不允许有遍历行为. 缺省情况下用deq ...
- STL源码剖析学习二:空间配置器(allocator)
STL源码剖析学习二:空间配置器(allocator) 标准接口: vlaue_type pointer const_pointer reference const_reference size_ty ...
- STL源码剖析学习之increment、decrement、dereference实现源码
//STL之increment.decrement.dereference实现源码 //学习目的:STL实现原理.操作符(++i,i++,*等操作符的重载) //increment/dereferen ...
- STL源码剖析—学习记录
提示:建议看完侯捷老师的STL标准库视频后,再看这本书,会看的下去一些!本人对其中重点内容和概念进行了提取,希望对一起前行的人有些许帮助,码字不易,欢迎点个赞呦! 文章目录 一.可能令你困惑的C++语 ...
- STL源码剖析学习十四:算法之set相关算法
STL中定义的set要求元素不得重复且已经排序 set算法要求的都是有序区间,但元素可以重复出现 另外提供的hash版本的set因为其元素无序,因此不能作为set函数的参数 set算法前4个参数分别表 ...
- 《STL源码剖析》学习--6章--_rotate算法分析
最近在看侯捷的<STL源码剖析>,其中有许多不太明白之处,后经分析或查找资料有了些理解,现记录一下. <STL源码剖析>学习--6章--random access ite ...
- 《STL源码剖析》学习--6章--power算法分析
最近在看侯捷的<STL源码剖析>,其中有许多不太明白之处,后经分析或查找资料有了些理解,现记录一下. 6章--power算法分析 书本中的算法如下所示: template <clas ...
- 《STL源码剖析》相关面试题总结
一.STL简介 STL提供六大组件,彼此可以组合套用: 容器 容器就是各种数据结构,我就不多说,看看下面这张图回忆一下就好了,从实现角度看,STL容器是一种class template. 算法 各种常 ...
- 【STL源码剖析】list模拟实现 | 适配器实现反向迭代器【超详细的底层算法解释】
今天博主继续带来STL源码剖析专栏的第三篇博客了! 今天带来list的模拟实现! 话不多说,直接进入我们今天的内容! 前言 那么这里博主先安利一下一些干货满满的专栏啦! 手撕数据结构https://b ...
最新文章
- 鸿蒙0s是什么意思,华为官宣,鸿蒙0S正式来临?
- cacti的mysql密码_cacti 监控搭建
- matlab导出jar包错误Error: An error occurred while shelling out to javac(erro code = 1)解决办法...
- 日常API之QQ登录
- decimal在存储过程和C#中的应用
- 快手“连横”京东,是志同道合还是抱团取暖?
- python编程,外星人飞船
- pyqt2_官网教程
- word 插入代码_突破Word页码困境,这招简单又实用的自动更新法,90%的人还不会!...
- 登入Github、Git本地上传及Visual Studio Code上传教程
- 数据科学和人工智能技术笔记 九、模型验证
- Android 系统 (129)---ODM 开发用户常见需求文档(三)
- 太难了!国内手机出货量大幅下降:华为跌幅小,小米跌惨了
- Java关键字---this的由来和其三大作用
- 集合点(掌握)-并发
- python ant_python3.7.1ant+TKinter在Tkin中显示来自ANT+设备的实时数据
- Java基础 第一节 第一课
- flutter图片切换闪一下
- C++中read和write的区别
- docker rabbitmq error: touch cannot touch ‘/etc/rabbitmq/rabbitmq.conf‘ permission denied