条款47:请使用traits classes表现类型信息(2)

条款47:请使用traits classes表现类型信息(2)
    Use traits classes for information about types.

    大家好,上一篇我们讨论了如何设计和实现traits classes,本篇将继续前面讨论来讲述如何使用traits classes
来表现类型信息.好,我们现在有了iterator_traits,我们可以可以这样来实现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 ) )
        ...
    }
    这看起来还行是吧,其实它却有些潜在的问题.首先将导致编译问题,我将在下一款讨论这一点,我们现在应该关心更根
本的问题.IterT类型在编译期间获知,所以iterator_traits<IterT>::iterator_category也可在编译期间确定.但if语句
确是在运行期才会核定.为什么将可在编译期完成的事情延期到运行期才做呢?这不仅浪费时间,也造成可执行文件膨胀.我
们真正想要的是一个条件式来判断'编译器核定成功'的类型.恰巧C++的重载机制就满足这个需求,哇哈哈!
    由于重载函数是根据传来的实参选择最佳的重载体,所以为了让advance的行为如我们所期望,我们需要产生几个接受不
同类型的iterator_category对象作参数的函数,我们将这函数取名为doAdvance:
    //这份实现用于random access迭代器
    template<typename IterT,typename DistT>
    void doAdvance( IterT& iter, DistT d, std::random_access_iterator_tag)
    {
        iter += d;
    }
    //这份实现用于bidirectional迭代器
    template<typename IterT,typename DistT>
    void doAdvance( IterT& iter, DistT d, std::bidirectional_iterator_tag)
    {
        if( d >= 0 ){
            while( d-- ){
                ++iter;
            }
        } else {
            while( d++ ){
                --iter;
            }               
        }
    }
    //这份实现用于input迭代器
    template<typename IterT,typename DistT>
    void doAdvance( IterT& iter, DistT d, std::input_iterator_tag)
    {
        if( d < 0 ){
            throw std::out_of_range( "Negative distance" );
        }
        while( d-- ){
            ++iter;
        }
    }
    有了这些doAdvance重载版本,advance需要做的只是调用它们并额外传递一个对象,后者必须带有适当的迭代器分
类,于是编译器运用重载机制调用适当的实现代码:
    template<typename IterT,typename DistT>
    void advance( IterT& iter, DistT& d ){
        doAdvance( iter, d, typename std::iterator_traits<IterT>::iterator_category() );
    }
    啦啦啦啦,搞定!现在我们来总结一下如何使用一个traits class了:
    ■ 建立一组重载函数或模板函数,彼此之间差异只在于各自的traits参数.令每个函数实现码与其接受之traits
信息相应和.   
    ■ 建立一个控制函数或函数模板,它调用上述重载函数并传递traits class所提供的信息.
    好了,今天任务完成!
    请记住:

    ■ Traits classes使得'类型相关信息'在编译期可用.它们以templates和'templates特化'完成实现.
    ■ 整合重载技术后,traits classes有可能在编译期对类型执行if...else测试.
   

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值