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

本文详细介绍了STL中的迭代器模式及其实现原理,并通过示例代码展示了find函数的具体实现过程。此外,还深入探讨了Traits编程技法,解释了如何通过特性萃取来统一不同迭代器的行为。

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

首先,先说说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++未能提供的关于型别认证方面的能力。弥补不为强型别语言的遗憾。


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值