c++ traits技法理解

本文深入探讨了C++Traits技法的应用,展示了如何通过traits增强模板的通用性和效率,特别是在迭代器处理方面。通过实例说明了traits如何区分不同类型的模板参数,并提供了一种灵活的迭代器类型识别方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

终于理解了c++ traits技法,不得不说它对c++的作用可以说是很大,让编程效率可以提升很多,为什么这多说,就是当我们在写了一个模板后,traits技法可以让这个模板的通用性更强,模板偏特化就会在模板泛化中再设计一个特别的版本,看下面这个列子,对于模板参数是一个一个普通类型时,它会匹配第一个模板,当为指针时匹配第二个模板,这就区分开了两种,可以有不同的处理方式

template<typename T>
struct A {
    
};

template<typename T>    //偏特化版本
struct A<T*> {
    
};

再看下面例子, 是traits在迭代器里简单应用的抽象例子,我们就可以根据模板里的参数类型来赋值,使其能调用相应的函数

template<class IterT>
struct my_iterator_traits {
    typedef typename IterT::value_type value_type;
};

template<class IterT>
struct my_iterator_traits<IterT*> {
    typedef IterT value_type;
};

void fun(int a) {
    cout << "fun(int) is called" << endl;
}

void fun(double a) {
    cout << "fun(double) is called" << endl;
}

void fun(char a) {
    cout << "fun(char) is called" << endl;
}

int main()
{
    my_iterator_traits<vector<int>::iterator>::value_type p;    //vector迭代器内部有一个typedef T value_type;有迭代器的value_type就可知类型
    fun(p);
    my_iterator_traits<int*>::value_type q;
    fun(q);
}

 来看一看iterator_traits的源码,对于iterator_traits类,通过调用它的iterator_category获得它的参数类型,即相应的迭代器类型,这样一来,我们就可以获取到任何类型的相应型别


template <class Iterator>
struct iterator_traits {
  typedef typename Iterator::iterator_category iterator_category;
  typedef typename Iterator::value_type        value_type;
  typedef typename Iterator::difference_type   difference_type;
  typedef typename Iterator::pointer           pointer;
  typedef typename Iterator::reference         reference;
};
/* 特化版本,迭代器是个原生指针
 */
template <class T>
struct iterator_traits<T*> {
  typedef random_access_iterator_tag iterator_category;
  typedef T                          value_type;
  typedef ptrdiff_t                  difference_type;
  typedef T*                         pointer;
  typedef T&                         reference;
};

/* 这里还要针对const T*特化
 * 否则还是依照上一个特化版本,value_type是const int而不是int
 */
template <class T>
struct iterator_traits<const T*> {
  typedef random_access_iterator_tag iterator_category;
  typedef T                          value_type;
  typedef ptrdiff_t                  difference_type;
  typedef const T*                   pointer;
  typedef const T&                   reference;
};




当用advance函数来计算两个迭代器间的距离时,可以获得其迭代器类型进行相应的操作,提高效率

template <class InputIterator, class Distance>
inline void __advance(InputIterator& i, Distance n, input_iterator_tag) {
  while (n--) ++i;
}

#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma set woff 1183
#endif

template <class BidirectionalIterator, class Distance>
inline void __advance(BidirectionalIterator& i, Distance n,
                      bidirectional_iterator_tag) {
  if (n >= 0)
    while (n--) ++i;
  else
    while (n++) --i;
}

#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma reset woff 1183
#endif

template <class RandomAccessIterator, class Distance>
inline void __advance(RandomAccessIterator& i, Distance n,
                      random_access_iterator_tag) {
  i += n;
}

template <class InputIterator, class Distance>
inline void advance(InputIterator& i, Distance n) {
  __advance(i, n, iterator_category(i));
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值