STL中成员类型的作用

今天被人问到STL中的某一个容器中说定义的成员类型是干嘛的,在这里我总结一下。

C++中的类成员有三部分:成员变量,成员函数,成员类型。

如果在类内部嵌套定义了一个类型,比如MyClass类中有一句 typedef int integer;那么就可以这样来定义变量 MyClass::integer a;  实际上就相当于定义了一个int 类型的变量a。 当然如果MyClass类作为模板的类型参数T的实参,在模板内,需要 typename T::integer a这样使用。

STL很大的一个好处是实现了算法与数据结构的解耦,也就是算法对于STL的容器具有普遍性,实现对容器抽象的通用算法。

比如algorithm中的find()函数,其实现如下:

template<class InputIterator, class T>
  InputIterator find (InputIterator first, InputIterator last, const T& val)
{
  while (first!=last) {
    if (*first==val) return first;
    ++first;
  }
  return last;
}
怎么做到对每种容器都适用呢,这就要使用STL中的嵌入的类型信息,也就是靠成员类型来实现。可以为每一种容器都定义Iterator 类型的成员类型,而且该成员类型必须能够进行 != 比较操作,*first解引用操作,++自增操作;简单的讲就是能够通过这个Iterator来遍历容器,并且能够访问对应位置的元素。

find 算法的思想很简单,从前到后遍历容器;访问容器中的每个元素与被查找的值进行比较。

问题在于,对于不同的容器,遍历方式不一样;访问下一个元素,对于vector,可能只是内部指针的 ++即可以;对于list,可能是内部指针的 p = p->next; 对于map,可能是内部指针模拟先序遍历等等;那么怎么屏蔽这些差异,实现语法上的一致性呢(consistency is good!),如果容器内部自定义的Iterator(虽然各自的Iterator内部实现不一样,封装内部的差异),只要让++操作都能访问到下一个元素,实现遍历不就行了。

所以总结来说,这些成员类型的作用是为了实现接口的统一,使算法对各种容器表现出一致性。也可以说,这些成员类型就相当于一组契约,只要遵守这些契约,那么便可以使用使用了这些契约的算法。

STL对这些契约有很强的依赖。

现在假若我不是对容器操作,也就是说不是对类对象操作,比如是指针,那么显然没办法嵌入类型信息。此时可以使用一个中间层,而不是嵌入的,提供更好的灵活性。这种技术就是traits技术,一个类模板,通过这个中间层类模板提供类型信息的集合。(下边是针对指针的特化版本,普通容器的是非特化版本,可以用来取代嵌入型的类型信息).

比如现在对容器中的每个元素一次进行某种操作:

首先定义traits中间层类型信息集合类模板,然后对指针类型进行特化,于是,可以看到最终的函数具有更多的类型适应性,也就是更加通用的算法,而且对于用户来说,这些都是隐藏的。

template <typename Container>
class ContainerTraits
{
    typedef typename Container::Elem Elem;
    typedef typename Container::InputIterator InputIterator;
};

template<>
class ContainerTraits<T*>
{
    typedef T Elem;
    typedef T* InputIterator;
};

template <typename Container>
typename ContainerTraits::Elem process(Container& c, int size)
{
    
}

通用算法,一直性真是个好东西。




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值