C++学习 9 深入STL 3

  • typename, typeid, iterator category
  • type traits , iterator traits
  • Iterator adapter, container adapter, Functor adaptor,

    typename, typeid, iterator category

    1. typename
      用法 1 在template< calss T, typename U >中用来取代class, 作用与class完全相同。
      用法 2 用于限定名中依赖模板形参 变量的声明 typedef 等。例:
      typedef typename T:: const_iterator *iter; ::表示限定名, 此处 T:: const_iterator 编译器无法预先判断是类型名, 必须加上 typename 限定。
      对于用于模板定义的依赖于模板参数的名称,只有在实例化的参数中存在这个类型名,或者这个名称前使用了typename关键字来修饰,编译器才会将该名称当成是类型。除了以上这两种情况,绝不会被当成是类型。
      这样编译器就可以确定T::iterator是一个类型,而不再需要等到实例化时期才能确定,因此消除了前面提到的歧义。

typename在下面情况下禁止使用:

    模板定义之外,即typename只能用于模板的定义中
    非限定类型,比如int,vector< int>之类
    基类列表中,比如template < class T> class C1 : T::InnerType不能在T::InnerType前面加typename
    构造函数的初始化列表中

如果类型是依赖于模板参数的限定名,那么在它之前必须加typename(除非是基类列表,或者在类的初始化成员列表中)
其它情况下typename是可选的,也就是说对于一个不是依赖名的限定名,该名称是可选的,例如vector< int> vi;

归根结底就是判断编译器能不能 认定声明是一个类型而不是 静态数据成员、静态成员函数和嵌套类型

 struct MyClass {
    static int A;
    static int B();
    typedef int C;
}

MyClass::A, MyClass::B, MyClass::C分别对应着上面三种。
参考:http://feihu.me/blog/2014/the-origin-and-usage-of-typename/
http://pages.cs.wisc.edu/~driscoll/typename.html
http://dev.yesky.com/13/2221013.shtml
2. typeid
typeid operator 头文件 < typeinfo>
用于1.一个多态对象的动态类型已知的情况下2. 静态数据类型。
用法 typeid(type),
typeid(expression) expression引用一个具有静态存续期的左值表达式, 此表达式是或者继承于多态类型 cosnt std::type。返回结果是const type_info&。不同编译器实现的type_info class各不相同。但c++标准保证它会实现一个name()方法,该方法返回类型名字的c-style字符串。
如果表达式的类型是类类型且至少包含有一个虚函数,则typeid操作符返回表达式的动态类型,需要在运行时计算;否则,typeid操作符返回表达式的静态类型,在编译时就可以计算。
参考:http://blog.csdn.net/zkybeck_ck/article/details/51762541
https://www.zhihu.com/question/38997922/answer/79179526
cpp refernce typeid
3. iterator category
头文件< stl_iterator>

//SGI 2.9 实现如下
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};

有五种类型对应迭代器定义如下:

template <class T, class Distance> struct input_iterator {
  typedef input_iterator_tag iterator_category;
  typedef T                  value_type;
  typedef Distance           difference_type;
  typedef T*                 pointer;
  typedef T&                 reference;
};

struct output_iterator {
  typedef output_iterator_tag iterator_category;
  typedef void                value_type;
  typedef void                difference_type;
  typedef void                pointer;
  typedef void                reference;
};

template <class T, class Distance> struct forward_iterator {
  typedef forward_iterator_tag iterator_category;
  typedef T                    value_type;
  typedef Distance             difference_type;
  typedef T*                   pointer;
  typedef T&                   reference;
};

template <class T, class Distance> struct bidirectional_iterator {
  typedef bidirectional_iterator_tag iterator_category;
  typedef T                          value_type;
  typedef Distance                   difference_type;
  typedef T*                         pointer;
  typedef T&                         reference;
};

template <class T, class Distance> struct random_access_iterator {
  typedef random_access_iterator_tag iterator_category;
  typedef T                          value_type;
  typedef Distance                   difference_type;
  typedef T*                         pointer;
  typedef T&                         reference;
};

不同容器迭代器对应 迭代器类型:
array random_access_iterator
vector random_access_iterator
list bidirectional_iterator
forward_list forward_iterator
deque random_access_iterator
set/multiset bidirectional_iterator
map/multimap bidirectional_iterator
unordered_set/unordered_multiset forward_iterator
unordered_map/unordered_multimap forward_iterator
istream_iterator input_iterator
ostream_iterator output_iterator

iterator category对算法的影响:用于指定重载类型。
例:

template <class InputIterator, class Distance>
inline void __distance(InputIterator first, InputIterator last, Distance& n, input_iterator_tag) {
  while (first != last) { ++first; ++n; }
}

template <class RandomAccessIterator, class Distance>
inline void __distance(RandomAccessIterator first, RandomAccessIterator last, Distance& n, random_access_iterator_tag) {
  n += last - first;
}
template <class InputIterator, class Distance>
inline void distance(InputIterator first, InputIterator last, Distance& n) {    
  typedef typename iterator_traits<InputIterator>::iterator_category category;
  __distance(first, last, n, category());//iterator_category(first));此为SGI2.9 实现。直接return该category 对象。与此处实现类似
}

之所以只重载input 和 random_access_ietrator_tag 两种是由于除了output_iterator_access_tag 之外其余均继承于input _iterator_access_tag .是IS-A 的关系, 此处只有 random 和其他计算方式不同故只重载两种。其他的实现还有偏特化版本。
例2.

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));
}

type traits , iterator traits

type traits
本质:加上一层间接性,换来以定的灵活性。通过偏特化来实现编译期类型判断, 参数传递优化等。

traits class是个类模板,在不修改一个实体(通常是数据类型或常量)的前提下,把属性和方法关联到一个编译时的实体。在c++中的具体实现方式是:首先定义一个类模板,然后进行显式特化或进行相关类型的部分特化。

我的理解是:traits是服务于泛型编程的,其目的是让模板更加通用,同时把一些细节向普通的模板用户隐藏起来。当用不同的类型去实例化一个模板时,不可避免有些类型会存在一些与众不同的属性,若考虑这些特性的话,可能会导致形成的模板不够“泛型”或是过于繁琐,而traits的作用是把这些特殊属性隐藏起来,从而实现让模板更加通用。
参考:http://blog.csdn.net/xiaoding133/article/details/7935309
http://www.cnblogs.com/pugang/archive/2012/10/17/2727378.html
http://www.cnblogs.com/youthlion/archive/2011/12/01/2255618.html
http://blog.csdn.net/xiaoding133/article/details/7930688

Iterator adapter, container adapter, Functor adaptor

  1. Iterator adapter
    insert iterators
    reverse iterators
    iostream iterators
  2. container adapter
    deque:stack、queue
    RB-tree:set、map
    参考:http://blog.csdn.net/wudaijun/article/details/14052783

  3. Functor adaptor
    通过模板类重载operator() 实现对functor的代理。
    bind,negate,compose
    头文件< functional>
    参考:http://blog.csdn.net/lanchunhui/article/details/50934031

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值