Effective C++ 条款47
本节条款的题目:请使用trait classes来表示类型信息
本节条款主要讲述的技术是怎样在编译期间实现对迭代器类型的推断,依据推断的类型进行最优处理。
我们先来看一下迭代器的种类:
1.input_iterator:仅仅读,仅仅能逐个前移
2.output_iterator:仅仅写,仅仅能逐个前移
3.forward_iterator:可读可写,仅仅能逐个前移
4.bidirectional_iterator:可读可写,支持逐个前移和后移
5.random_access_iterator:可读可写,支持随机訪问(随意步数移动)
假设一下,假设有一个函数用于对迭代器指定移动次数d,我们怎样实现这个函数,以达到最理想的状态。
我们肯定会处理迭代器是random access类型的情况和不是random access类型的情况。当时random access的时候,直接加减迭代器在常数时间内完毕,假设不是,仅仅能一步一步向前或向后移动。
例如以下代码:
template<typename Iter, typename DistT>
void advance(IteT& iter,DistT d)
{
if(iter is a random access iterator)
iter+=d;
else
{
if(d>=0)
while(d--) ++iter;
else
while(d++) --iter;
}
}
但是,我们怎么才干做到“iter is a random access iterator”在编译期间的实现?
实现这个功能。须要下面几步,而且相对繁杂的几步。
首先为每一种迭代器设置struct标签,每一个struct都是空的结构体,例如以下代码:
struct input_iterator_tag{};
struct output_iterator_tag{};
struct forward_iterator_tag: public input_iterator_tag{};
struct bidirectional_iterator: public forward_iterator_tag{};
struct random_access_iterator: public bidirectional_iterator_tag{};
接着。我们就要引入traits,traits是一种技术,我们通过程序来看一下这是什么技术。有什么用。
我们来看一下关于各种容器的定义:
template class <T>
class vector
{
public:
class iterator
{
public:
typedef random_access_iterator iterator_category;
…
}
…
}
template class <T>
class list
{
public:
class iterator
{
public:
typedef bidirectional_iterator iterator_category;
…
}
…
}
从上面代码能够看出,每一个容器中都有一个iterator类。但是每一个iterator类中的迭代器标签却不一样。
当我们调用语句vector<int>::iterator::iterator_category时会返回random_access_iterator类的类型,当我们调用list<int>::iterator::iterator_category时会返回bidirectional_iterator类的类型。
我们再来看一下有关iterator_traits结构体的定义,
template<typename IterT>
struct iterator_traits{
typedef typename IterT::iterator_category iterator_category;//typedef typename的使用见条款42
};
假设我们通过语句iterator_traits<vector<int>::iterator>::iterator_category调用就会返回有关vector<int>迭代器iterator的类型,该语句返回random_access_iterator类型。
同理iterator_traits<list<int>::iterator>::it
Effective C++ 条款47的更多相关文章
- Effective C++ -----条款47:请使用traits classes表现类型信息
Traits classes使得“类型相关信息”在编译期可用.它们以template和“templates特化”完成实现. 整合重载技术(overloading)后,traits classes有可能 ...
- EC读书笔记系列之18:条款47、48
条款47 请使用traits classes表现类型信息 记住: ★Traits classes使得“类型相关信息”在编译期可用.它们以templates和“templates特化”完成实现 ★整合重 ...
- [More Effective C++]条款22有关返回值优化的验证结果
(这里的验证结果是针对返回值优化的,其实和条款22本身所说的,考虑以操作符复合形式(op=)取代其独身形式(op),关系不大.书生注) 在[More Effective C++]条款22的最后,在返回 ...
- More Effective C++ 条款0,1
More Effective C++ 条款0,1 条款0 关于编译器 不同的编译器支持C++的特性能力不同.有些编译器不支持bool类型,此时可用 enum bool{false, true};枚举类 ...
- Effective C++ 条款08:别让异常逃离析构函数
1.别让异常逃离析构函数的原因 <Effective C++>第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常.多个异常同时存在的情况下, ...
- Effective C++ -----条款28:避免返回handles指向对象内部成分
避免返回handles(包括reference.指针.迭代器)指向对象内部.遵守这个条款可增加封装性,帮助const成员函数的行为像个const,并将发生“虚吊号码牌”(dangling handle ...
- Effective C++ -----条款21:必须返回对象时,别妄想返回其reference
绝不要返回pointer或reference指向一个local stack对象,或返回reference指向一个heap-allocated对象,或返回pointer或reference指向一个loc ...
- Effective C++ -----条款19:设计class犹如设计type
Class的设计就是type的设计.在定义一个新type之前,请确定你已经考虑过本条款覆盖的所有讨论主题. 新type的对象应该如何被创建和销毁? 对象的初始化和对象的赋值该有什么样的区别? 新typ ...
- Effective C++ -----条款18:让接口容易被正确使用,不易被误用
好的接口很容易被正确使用,不容易被误用.你应该在你IDE所有接口中努力达成这些性质. “促进正确使用”的办法包括接口的一致性,以及与内置类型的行为兼容. “阻止误用"的办法包括建立新类型.限 ...
随机推荐
- POJ1258 Agri-Net(Prim)
Agri-Net Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 51685 Accepted: 21558 Descri ...
- order by 中利用 case when 排序
order by case when a.ShopNumber in(1,2,3) then 0 else 1 end
- Servlet 2.3 规范
Servlet2.3规范 第一章: servlet2.3规范用到了一下的一些规范:J2EE.JSP1.1.JNDI 在14章中讲述了规范中的所有的classes类或接口(改文中不讲述).对开发者而言以 ...
- [BZOJ3816][清华集训2014]矩阵变换(稳定婚姻问题)
3816: 矩阵变换 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 803 Solved: 578[Submit][Status][Discuss] ...
- [HDU6268]Master of Subgraph
[HDU6268]Master of Subgraph 题目大意: 一棵\(n(n\le3000)\)个结点的树,每个结点的权值为\(w_i\).给定\(m(m\le10^5)\),对于任意\(i\i ...
- 设置html属性为disabled时flask后台获取数据失败
标签input的值如果不需要用户修改,则设置属性为 readonly,不要设置为 disabled.因为设置disabled会导致flask后端获取不到这个input得value rule_maker ...
- android 两次调用DatePickerDialog.onDateSet()
在4.2.2版本号上调用系统的DatePickerDialog,发现点击确定时系统调用onDateSet()两次,须要过滤当中的一次. Calendar mCalendar = Calendar.ge ...
- centos7 安装nginx与配置
第一步安装 使用Yum安装是推荐的方式,整体的流程非常的简单,也不容易出错,如果不需要什么特殊配置,建议使用Yum尽进行安装. 第一种安装方式,通过添加epel源 yum install epel-r ...
- CMD/AMD的原理、区别和应用
有必要简单提一下两者的主要区别: 1.CMD推崇依赖就近,可以把依赖写进你的代码中的任意一行,例: define(function(require, exports, module) { var a ...
- mac更新系统后Git不能用,提示missing xcrun at
今天更新了mac系统,然后就踩了这个坑. 启动AndroidStudio 右上角提示: can't start git: /usr/bin/git probably the path to git e ...