博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【C++】traits classes
阅读量:7089 次
发布时间:2019-06-28

本文共 2046 字,大约阅读时间需要 6 分钟。

程序开发时,经常遇到根据变量获取其类型信息的需求.

例如,某一个函数针对不同的类型参取了不同的优化策略,因而要获取相应的类型信息调用对应的函数.

template
//将迭代器向前移动d单位void advance(IterT& iter,DistT d); //如果d < 0则向后移动

观念上advance只是做iter += d动作,但其实不可以全然那么实践.因为只有random access迭代器才支持+=操作,面对其他威力不那么强大迭代器种,advance必须反复施行++或--,共d次.因而希望其实现方式如下:

template
void advance(IterT& iter,DistT d){ if(iter is a random access iterator) { iter += d; //针对random access 迭代器使用迭代器算术运算 } else{ //针对其他迭代器分类,反复调用++或-- if(d >= 0) {
while(d--) ++iter;} else {
while(d++) --iter;} }}

其中,关键是如何判断类型为IterT的iter是否为random access迭代器

初步想法,可以在类型中定义相应的类型信息属性,标识该类型所包含的类型信息,然后通过获取该类型的这些信息属性,进行判断.

这种想法,可以解决自定义类型的问题,但无法解决内置类型的问题,因为我们无法将信息嵌套于原始指针内.

因此,上述想法行不通,我们需要把类型的类型信息放于类型自身之外.

traits classes就是一种技术,也是个C++程序员共同遵守的协底色,它要求对内置类型和用户自定义类型表现一样.

这种技术可以允许我们在编译期间取得某些类型信息.一个traits class设计与实现的一般步骤如下:

1.确认若干你希望将来可取得的类型相关信息.

2.为该信息选择一个名称

3.提供一个template和一组特化版本,内含你希望支持的类型相关信息.

有了相关的trait class,我们可以用trait class提供的信息类型,取代if语句中的条件判断.

这样实现,将会存在一个问题,编译期完成的事被延到运行期了.

这是因为traits class可以在编译期间获知IterT的类型,但if语句却是在运行期才会判断.

这里就需要一种方法,可以在编译期完成类型的判断,取代if语句的判断.

该方法就是重载,根据编译期间确定的类型信息,选择最合适的重载函数,相当根据if语句判断后,再选择具体的实现.

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

trait class具体的使用方法,如上述代所述.

1.建立一组重载函数或函数模板,彼此间的差异只在于各自的traits参数.令每个函数实现码与其接受的traits信息相匹配.

2.建立一个控制函数或函数模板,它调用上述的那些重载函数并传递traits class所提供的信息.

启发:解决问题时,思路的逐步深入,遇到问题,可以先想个初步思路,然后分析初步思路不足,并改进初步思路,提供合理的解决方案.

参考资料:Effective C++

转载地址:http://styql.baihongyu.com/

你可能感兴趣的文章
Consul安装使用
查看>>
tomcat事件处理机制
查看>>
JS BUG 传递数字过大,数据值会变化
查看>>
橡皮筋进度条ElasticProgressBar
查看>>
spring boot引入json,jsonobject,需要指定jdk15
查看>>
企业架构 - 涉众管理(Stakeholder Management)
查看>>
Ubuntu11.10 解决rar文件解压错误
查看>>
sqlplus: error while loading shared libraries: /u01/app/lib/libclntsh.so.11.1
查看>>
ORACLE等待事件:enq: TX - row lock contention
查看>>
使用Fiddler2录制HTTP操作脚本
查看>>
响应activex事件
查看>>
Winform 进程之间通讯的几种方法
查看>>
c++中冒号(:)和双冒号(::)的用法
查看>>
dubbo工作原理
查看>>
驱动开发利器Microsoft Windows Driver Kit 7.1.0下载
查看>>
maven_项目的依赖、聚合、继承
查看>>
一个C++类的注释:
查看>>
Winsock IO模型之select模型
查看>>
开发规范
查看>>
PHP json_decode object时报错Cannot use object of type stdClass as array
查看>>