C++沉思录__迭代器适配器

前文所述的5个主要的几个迭代器,都是内置于于STL中的标准容器,用法也只能针对标准容器。STL在不断的演变中,STL的爱好者扩充了迭代器的内容,他们在迭代器的基础上发展而来,叫迭代器适配器,他提供了更多的操作功能,也不仅仅局限于容器,还可以应用于更多方面。正如容器有标准容器和容器适配器,仿函数有标准仿函数和仿函数适配器,这里的迭代器适配器也是一样的道理。显然他们都是在原有迭代器的基础之上发展而来的,所以基础迭代器拥有的他们都拥有。

这里的难点在于如何理解“适配器”,所谓的适配器,我们可以通过下面的例子进行了解,先放结论:我们有一个需求,需要查找数组中最后一个值等于42的元素,对于已有的find函数和双向迭代器来说,我们只能够找到第一个值等于42的元素,而无法满足要求,当然,在已有的数据结构的基础上,我们可以重新编写算法,但是对于同样一个数据结构,却要用不同的算法来解决,这不是我们想要的,这个时候,我们需要的是从后往前遍历元素。这个时候,我们对原有的迭代器进行改造,使得改造后的迭代器能够满足原有算法的需要。(用书上的话来说就是:我们原来有一个接口,但是这个接口不是我们想要的,我们就把已有类适配成所需要的接口)所谓的适配,就是对原有的迭代器进行改造,使其能够用原有算法实现不同的需求。“把已有类'适配'成所需要的接口“)。

举例说明:对双向迭代器改造后的迭代器适配器,这是一种反向迭代器(正向迭代器)。顾名思义,反向迭代器会提供与普通迭代器相反方向的遍历功能。反向迭代器其实一个正向迭代器的适配器,它的实现都是通过调用正向迭代器的操作,为了与迭代器的概念保持一致(begin指向迭代器的第一个元素,end指向迭代器的最后一个元素的下一个位置),又与正向迭代器有一点点不同。reverse_iterator的实现中有一个名为current的Iterator,它是模板参数,即正向迭代器。正向迭代器指向的范围是序列中的第一个元素到最后一个元素的下一个位置,为了保持迭代器概念的统一,反向迭代器的rbegin应该是序列的最后一个元素,rend应该是第一个元素前面的元素。

template<class It ,class T>
class Rev
{
    friend bool operator==(const Rev &x, const Rev &y)
    {
        return  x.it == y.it;
    }
    friend bool operator!=(const Rev &x, const Rev &y)
    {
        return !(x.it == y.it);
    }
    public:
    Rev()
    {

    }
    Rev(It i):it(i)
    {

    }
    operator It()//类型转换 遇到It就转换成it
    {
        return it;
    }
    //将参数迭代器反向
    Rev& operator++()
    {
        --it;
        return *this;
    }
    Rev operator--()
    {
        ++it;
        return *this;
    }
    Rev& operator++(int)
    {
        Rev r = *this;
        it++;
        return r;
    }
    Rev operator--(int)
    {
        Rev r = this;
        it--;
        return r;
    }
    T & operator*()
    {
        It i = it;
        return *--i;
    }
private:
        It it;

};

find实现

template<class P,class T>
P find(P start,P end,const T& x)
{
    while(start !=end&& *start != x)
    {

    ++start;
    }
    return start;
}

测试

typedef Rev<int * ,int> R;
int main(int argc, char const *argv[])
{

    int x[100];
    for(int i =0;i<100;i++)
    {
        x[i]  =i+1;
    }
    int *p = find(x,x+100,42);
    R r = find(R(x+100),R(x),42);
     cout<<*r<<endl;//r本身是对象可以调用公用方法
      cout<< *p<<endl;
     system("pause");
    
     
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_39804483/article/details/83032994