Effective C++ Item 47 请使用 traits classes 表现类型信息

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie

经验:Traits classes 使得"类型相关信息"在编译期可用。它们以 templates 和 "templates 特化"完成实现

示例:

template<...>
class deque{
public:
	class iterator{
	public:
		typedef random_access_iterator_tag iterator_category;
	};
};
//template
template<typename IterT>
struct iterator_traits{
	typedef typename IterT::iterator_category iterator_category;
};
//template 偏特化
template<typename IterT>
struct iterator_traits<IterT *> // template 偏特化,限制 IterT 必须是指针
{
	typedef random_access_iterator_tag iterator_category;
};

//实现 advance
template<typename IterT, typename DistT>
void advance(IterT &iter, DistT d){
	if(typeid(typename std::iterator_traits<IterT>::iterator_category) == typeid(std::random_access_iterator_tag))
	...
}

解析:上面 iterator_traits<IterT>::iterator_category 在编译期就可确定,但 if 语句却是在运行期才会核定,浪费时间,也造成可执行文件的膨胀。

纠正:融合重载技术后,traits classes 有可能在编译期对类型执行 if...else 测试

template<typename IterT, typename DistT>
void advance(IterT &iter, DistT d){
	doAdvance(iter, d, typename std::iterator_traits<T>::iterator_category());
}

template<typename IterT, typename DistT>
void advance(IterT &iter, DistT d, std::random_access_iterator_tag){
	iter += d;
}

template<typename IterT, typename DistT>
void advance(IterT &iter, DistT d, std::bidirectional_iterator_tag){
	if(d >= 0){while(d--) ++iter;}
	else{while(d++) --iter;}
}

template<typename IterT, typename DistT>
void advance(IterT &iter, DistT d, std::input_iterator_tag){
	if(d < 0) throw std::out_of_range("Negative distance");
	while(d--) ++iter;
}

Effective C++ Item 47 请使用 traits classes 表现类型信息

时间: 2024-10-09 21:57:43

Effective C++ Item 47 请使用 traits classes 表现类型信息的相关文章

Effective C++ 条款47 请使用traits classes表现类型信息

1. STL迭代器分类: input迭代器:只能一次一步向前移动,客户只可读取(不能涂写)且只能读取一次它们所指的东西,模仿指向输入文件的阅读指针.例如istream_iterators output迭代器:与input迭代器类似,但"一切只为输出",只能一次一步向前移动,客户只可涂写(不能读取)且只能涂写一次它们所指向的东西,模仿指向输出文件的涂写指针.例如ostream_iterators. forward迭代器:具有input迭代器和output迭代器的所有功能:只能一次一步向前

Item 47:使用Traits类提供类型信息

Item 47: Use traits classes for information about types. C++中的 Traits 类可以在编译期提供类型信息,它是用Traits模板及其特化来实现的. 通过方法的重载,可以在编译期对类型进行"if-else"判断.我们通过STL中的一个例子来介绍Traits的实现和使用. 本文以iterator_traits为例介绍了如何实现traits类,以及如何使用traits类(在Item 42中提到过iterator_traits).

条款47:请使用traits class表示类型信息

在stl的算法中,我们的希望往往是根据不同的迭代器类型进行不同的更有效率的操作: 1 template<typename IterT, typename DistT> 2 void advance(IterT iter, DistT dis) 3 { 4 if(iter is a random access iterator) 5 iter += dis; 6 else{ 7 if(dis >= 0){ 8 while(dis--) 9 iter++; 10 }else{ 11 whil

读书笔记 effective c++ Item 47 使用traits class表示类型信息

STL主要由为容器,迭代器和算法创建的模板组成,但是也有一些功能模板.其中之一叫做advance.Advance将一个指定的迭代器移动指定的距离: 1 template<typename IterT, typename DistT> // move iter d units 2 void advance(IterT& iter, DistT d); // forward; if d < 0, 3 // move iter backward 从概念上来说,advance仅仅做了it

Effective JavaScript Item 47 绝不要向Object.prototype中添加可列举的(Enumerable)属性

本系列作为Effective JavaScript的读书笔记. 如果你的代码中依赖于for..in循环来遍历Object类型中的属性的话,不要向Object.prototype中添加任何可列举的属性. 但是在对JavaScript执行环境进行增强的时候,往往都需要向Object.prototype对象添加新的属性或者方法.比如可以添加一个方法用于得到某个对象中的所有的属性名: Object.prototype.allKeys = function() { var result = []; for

Effective C++ Item 46 需要类型转换时请为模板定义非成员函数

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:当我们编写一个 class template, 而它所提供之"与此 template 相关的"函数支持"所有参数之隐式类型转换"时,请将那些函数定义为 "class template内部的 friend 函数". 示例: template<typename T> class Rational{ public: Ration

Effective C++ Item 48 认识 template 元编程

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:Template metaprogramming (TMP, 模板元编程)可将工作由运行期移往编译期,因而得以实现早期错误侦测和更高的执行效率 示例1: template<typename IterT, typename DistT> void advance(IterT &iter, DistT d){ if(typeid(typename std::iterator_t

Effective C++ Item 31 降低文件间编译依存关系

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:支持"编译依存性最小化"的一般构想是:相依于声明式,不要相依于定义式. 基于此构想的两个手段是 Handle classes 和 Interface classes. 示例:相依于定义式 #include <string> #include "date.h" #include "address.h" class Perso

Effective C++ Item 25 考虑写出一个不抛异常的swap函数

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定这个函数不抛出异常 示例: stl里的swap算法 namespace std{ template<typename T> void swap(T &a, T &b){ T temp(a); a = b; b = temp; } } //"pimpl手法"(pointer