STL中迭代器概念与traits编程技法

首先,先说说iterator的定义。

iterator模式:提供一种方法,使之能够依序巡防某个容器所含的各个元素,而又无需暴露改容器的内部表达方式。

STL的中心思想在于:将数据容器和算法分开,彼此独立设计。然后再将其撮合在一起。容器和算法的泛型化。

下面的代码是STL里面find函数的实现代码

#include <vector>
#include <list>
#include <deque>
#include <algorithm>
#include <iostream>
using namespace std;
namespace TEST
{
    template <class InputIterator, class T>
    InputIterator find(InputIterator first, InputIterator last, const T& value)
    {
        while(first != last && *first != value)
        {
            ++first;
        }
        return first;
    }
}




int main()
{
    const int arraySize = 7;


    int ia[arraySize] = {0, 1, 2, 3, 4, 5, 6};


    vector<int> ivect(ia, ia + arraySize);
    list<int> ilist(ia, ia + arraySize);
    deque<int> ideque(ia, ia + arraySize);


    vector<int>::iterator it1 = TEST::find(ivect.begin(), ivect.end(), 4);


    if (it1 == ivect.end())
    {
        cout << "4 not found." << endl;
    }
    else
    {
        cout << "4 found." << *it1 << endl;
    }


    list<int>::iterator it2 = TEST::find(ilist.begin(), ilist.end(), 6);


    if (it2 == ilist.end())
    {
        cout << "6 not found." << endl;
    }
    else
    {
        cout << "6 found." << *it2 << endl;
    }


    deque<int>::iterator it3 = TEST::find(ideque.begin(), ideque.end(), 8);


    if (it3 == ideque.end())
    {
        cout << "8 not found." << endl;
    }
    else
    {
        cout << "8 found." << *it3 << endl;
    }


    return 0;
};


这段代码虽然很简单。但是也从本质的说明了我们常用的find函数的实现。


迭代器是一种智能指针

迭代器是一种行为类似指针的对象。智能指针(smart pointer)的一种通用实现技术是使用引用计数(reference count)。智能指针类将一个计数器与类指向的对象相关联,引用计数跟踪该类有多少个对象共享同一指针。


使用迭代器总结:

#include <iostream>
#include <vector>
#include <map>
#include <stdio.h>
using namespace std;


int main()
{
    int data[7] = {1, 2, 3, 4, 5, 6, 7};
    /*vector<int> m_vector(data, data + 7);


    vector<int>::iterator it = m_vector.begin();*/


    map<int, int> m_map;


    for (int i = 0; i < 7; i++)
    {
        m_map[i] = i;
    }


    map<int, int>::iterator it = m_map.begin();


    printf("%p\n", it);
    it++;
    printf("%p\n", it);
    return 0;
}

it的地址没变。说明it++没有改变it的地址。也说明了,it++改变的是智能指针的计数器。通过改变计数器来达到遍历容器数据的目的。


下面介绍一下Traits编程技法。Traits编程技法是STL源代码的钥匙。

下面一段代码使用内嵌型声明方法。

#include <iostream>
using namespace std;


template <class T>
struct MyIter
{
    typedef T value_type;
    T* ptr;
    MyIter(T* p = 0) : ptr(p){}
    T& operator*() const {return *ptr;}
};


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


int main()
{
    MyIter<int> ite(new int(8));
    cout << func(ite) <<  endl;


    return 0;
};

上面这种方法可以帮我们得到 template情景下的返回值。


traits扮演的角色是“特性萃取机”角色。萃取各种迭代器的特性。这里的迭代器特性,指的是迭代器的相应型别。

特性萃取机能够有效运作,每一个迭代器必须遵守约定。

最常用的迭代器相应型别有五种:value type, difference type, pointer, reference, iterator catagoly。

迭代器相应型别之一:value type

所谓value type, 是指迭代器所指对象的型别。任何一个打算与STL算法有完美搭配的class,都应该定义自己的value type内嵌型别。

迭代器相应型别之二:difference type

difference tyoe用来表示两个迭代器之间的距离。因此也可以用来表示一个容器的最大容量,因为对于连续空间而言,头尾之间的距离

就是其最大容量。

迭代器相应型别之三:reference type

迭代器分为两种:不允许改变“所指对象之内容”和允许改变“所指对象之内容”。

迭代器相应型别之四:pointer type

pointers和references。就是在萃取器里面传回一个pointer,指向迭代器所指之物。

迭代器相应型别之五:iterator_category

根据移动特性与施行操作,迭代器被分为五类。

intput iterator:只能读的迭代器。

output iterator:只能写的迭代器。

forward iterator:允许写入型算法。

bidirectional Iterator:可双向移动。

random access iterator:蕴涵所有指针算术能力。





#pragma once
#include <iostream>
using namespace std;


struct B 
{


};


struct D1 : public B 
{


};


struct D2 : public D1 
{


};


template <class T>
func(T& p, B)
{
    cout << "B version" << endl; 
}


template <class T>
func(T& p, D2)
{
    cout << "D2 version" << endl;
}

有template的文件必须在*.h里面,要不然会出错。

 int main()
{
    int p;


    func(p, B());
    func(p, D1());
    func(p, D2());


    return 0;
};

输出结果是


上述代码必须排除error4430才行。

这段代码主要说明了,类和继承的关系。


总结:设计适当的相应型别,是迭代器的责任。设计适当的迭代器,则是容器的责任。

taits编程技法大量运用于STL实现品中。它利用内嵌型别的编程技巧与编译器的template参数推导功能。增强

C++未能提供的关于型别认证方面的能力。弥补不为强型别语言的遗憾。


汗,还是照本宣科。上面部分是我看得懂的。希望对大家有帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STL(Standard Template Library)是C++标准库的一个重要组成部分。它提供了一系列的模板容器和算法,其迭代器(Iterator)是STL的一个重要概念迭代器是一种类似于指针的对象,用于遍历容器的元素。它提供了一组操作,包括解引用、移动等,使得我们可以在不了解容器内部结构的情况下访问和操作容器的元素。 在STL迭代器分为五种类型: 1. 输入迭代器(Input Iterator):只能读取容器的元素,且只能进行单步前进操作。 2. 输出迭代器(Output Iterator):只能写入容器的元素,且只能进行单步前进操作。 3. 前向迭代器(Forward Iterator):可以读取和写入容器的元素,且可以进行多步前进操作。 4. 双向迭代器(Bidirectional Iterator):可以读取和写入容器的元素,且可以进行多步前进和后退操作。 5. 随机访问迭代器(Random Access Iterator):具有双向迭代器的所有功能,并且支持随机访问和指针算术运算。 对于不同的STL容器,可以使用对应的迭代器类型来进行遍历和操作。例如,对于vector容器可以使用随机访问迭代器,对于list容器可以使用双向迭代器。 以下是一个使用迭代器遍历vector容器的示例代码: ```cpp #include <iostream> #include <vector> int main() { std::vector<int> nums = {1, 2, 3, 4, 5}; // 使用迭代器遍历容器 std::vector<int>::iterator it; for (it = nums.begin(); it != nums.end(); ++it) { std::cout << *it << " "; } return 0; } ``` 在上述代码,我们定义了一个vector容器nums,并使用迭代器it进行遍历。通过调用`begin()`函数可以获取指向容器第一个元素的迭代器,调用`end()`函数可以获取指向容器最后一个元素之后位置的迭代器。在循环,通过解引用操作`*it`来获取迭代器指向的元素的值。 需要注意的是,当遍历结束后,迭代器会指向容器最后一个元素之后的位置,即`nums.end()`。因此,循环条件使用`it != nums.end()`来判断是否遍历完成。 这只是使用迭代器的简单示例,STL还有许多其他功能强大的算法和容器可以与迭代器一起使用。通过灵活运用迭代器,我们可以更方便地操作和处理STL容器的元素。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值