首页 > 编程语言 >[STL] 3 迭代器概念与 traits 编程技法

[STL] 3 迭代器概念与 traits 编程技法

时间:2023-03-11 17:36:23浏览次数:47  
标签:typedef 迭代 iterator STL traits template type

3 迭代器概念与 traits 编程技法

3.1 迭代器设计思维—— STL 关键所在

中心思想在于将数据容器和算法分开。

3.2 迭代器是一种智能指针

迭代器最重要的编程工作是对 operator*operator-> 进行重载。

每一种 STL 容器都提供有专属迭代器以隐藏容器的设计细节。

3.3 迭代器相应型别

运用迭代器时有时需要获取对应的型别,某些情况下可以通过模板推导。

3.4 traits 编程技法—— STL 源代码门钥

设计模板类专门用于萃取迭代器的特性,包括迭代器指向的数据类型,使用方法如下

template<class I>
struct iterator_traits {
    typedef typename I::value_type value_type;
}

在实例化前,typedef 并不知道 I::value_type 是什么,可能为数据成员或成员函数或嵌套类型,因此加上 typename 关键字告知 typedef 它是一个类型。这样在迭代器中就可以使用迭代器指向的数据类型了,比如

template<class T>
typename iterator_traits<I>::value_type func(I ite) {
    return *ite;
}

但当迭代器指向类型为指针或 const 指针时,则需要特化模板函数,使用

template<class I>
struct iterator_traits<I*> {
    typedef T value_type;
}

template<class I>
struct iterator_traits<const T*> {
    typedef T value_type;
}

即可萃取正确的类型。

3.4.1 迭代器相应型别之一:value_type

value_type 是迭代器所指向对象的型别,定义方法同上。

3.4.2 迭代器相应型别之二:difference_type

difference_type 表示两个迭代器之间的距离,也可以表示最大容量。如果泛型算法提供计数功能,则必须返回 difference_type 类型,比如

template<class I, class T>
typename iterator_traits<I>::difference_type count(I first, I last, const T& value) {
    typename iterator_traits<I>::difference_type n = 0;
    for ( ; first != last; ++first) {
        if (*first == value) {
            ++n;
        }
    }
    return n;
}

针对其他型别,有

// Provide type ptrdiff_t
#include <cstddef>

template<class I>
struct iterator_traits<T*> {
    typedef ptrdiff_t difference_type;
}

template<class I>
struct iterator_traits<const T*> {
    typedef ptrdiff_t difference_type;
}

3.4.3 迭代器相应型别之三:reference_type

3.4.4 迭代器相应型别之四:pointer_type

这两种型别分别对应迭代器的引用和指针类型,使用方法如下

template<class I>
struct iterator_traits {
    typedef typename I::pointer pointer;
    typedef typename I::reference reference;
}

template<class I>
struct iterator_traits<I*> {
    typedef I* pointer;
    typedef I& reference;
}

template<class I>
struct iterator_traits<const I*> {
    typedef const I* pointer;
    typedef const I& reference;
}

3.4.5 迭代器相应型别之五:iterator_category

迭代器可以被分为五类,只读、只写、区间读写 ++、双向移动 --、随机访问。因为访问方法不同,因此调用函数时需要针对不同的迭代器类型设计不同的函数,最后根据 traits 获取迭代器类型,根据多态使用不同函数。

// Predefined tag
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 { };

// Design function for different iterator
template<class InputIterator, class Distance>
inline void __advance(InputIterator & i, Distance n, input_iterator_tag) { ... }
template<class ForwardIterator, class Distance>
inline void __advance(ForwardIterator & i, Distance n, forward_iterator_tag) { ... }
template<class RandomAccessIterator, class Distance>
inline void __advance(RandomAccessIterator & i, Distance n, random_access_iterator_tag) { ... }

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

template<class I>
struct iterator_traits {
    typedef typename I::iterator_category iterator_category;
}

template<class I>
struct iterator_traits<T*> {
    typedef random_access_iterator_tag iterator_category;
}

template<class I>
struct iterator_traits<const T*> {
    typedef random_access_iterator_tag iterator_category;
}

3.5 std::iterator 的保证

任何迭代器都拥有以上的五个内嵌型别,STL 提供了 iterator 基类,设计的迭代器继承自它,就可以满足 STL 规范。

template<class Category, class T, class Distancee = ptrdiff_t, class Pointer = T*, class Reference = T&>
struct iterator {
    typedef Category iterator_category;
    typedef T value_type;
    typedef Distance difference_type;
    typedef Pointer pointer;
    typedef Reference reference;
}

它是纯粹的型别定义,不包含任何成员。

3.6 iterator 源代码完整重列

3.7 SGI STL 的私房菜:__type_traits

标签:typedef,迭代,iterator,STL,traits,template,type
From: https://www.cnblogs.com/futureknight/p/17206510.html

相关文章

  • PentestLab-web安全SQL注入-EXP2
    我们打开pentestlab靶机选择“sql  injections”选择“Example2”观察页面发现name是注入点使用工具测试sqlmap参数为pythonsqlmap.py-u"http://192.168.29.148/sqli/......
  • 可迭代对象和迭代器对象以及for循环的本质
    一、可迭代对象什么是可迭代对象:在数据类型的后面可以使用点加__iter__(.__iter__)来判断是不是可迭代对象不是可迭代对象:intfloatbool函数对象可迭代对象:s......
  • 面试之可迭代对象和迭代器对象以及for循环的本质
    一、可迭代对象什么是可迭代对象:在数据类型的后面可以使用点加__iter__(.__iter__)来判断是不是可迭代对象不是可迭代对象:intfloatbool函数对象可迭代对象:s......
  • Python迭代与生成器
    1、迭代_iter_对象方法可迭代对象,返回迭代器__next_对象方法迭代器对象,返回迭代中每一步的运算iter(object)内置函数得到object的迭代器next(object)......
  • 生成器,迭代器
    迭代器迭代器分为迭代器对象和可迭代对象,迭代就是每一次的结果都必须依赖于上一次的结果,能够通过for循环进行迭代操作,也能够通过__next__方法进行迭代操作可迭代对象内......
  • STL:map映照容器的简单用法(poj 2503 Babelfish)
    STL中map映照容器由一个键值和一个映照数据组成,具有一一对应的关系。结构为:键值--映照数据       例: aaa --111             bbb--222   ......
  • 链表指针指迷了我(UVA 11988 STL deque)
    BrokenKeyboard(a.k.a.BeijuText)You'retypingalongtextwithabrokenkeyboard.Wellit'snotsobadlybroken.Theonlyproblemwiththekeyboardisthats......
  • Leetcode69(牛顿迭代)
    给你一个非负整数 x ,计算并返回 x 的 算术平方根 。由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去。注意:不允许使用任何内置指数函数和算符,例如 ......
  • 迭代器
    内置有__iter__方法的对象都是可迭代对象'''内置的意思是python自带的,解释器中已经存在的,我们可以直接使用的'''目前所学的数据类型#目前我所学的数据类型中,有哪些是可......
  • Python 异步: 异步迭代器(15)
    动动发财的小手,点个赞吧!迭代是Python中的基本操作。我们可以迭代列表、字符串和所有其他结构。Asyncio允许我们开发异步迭代器。我们可以通过定义一个实现aiter()和......