为啥 c++ 顺序访问迭代器的函数签名不使用指针?

Posted

技术标签:

【中文标题】为啥 c++ 顺序访问迭代器的函数签名不使用指针?【英文标题】:Why does function signature for c++ sequential access iterator not use pointers?为什么 c++ 顺序访问迭代器的函数签名不使用指针? 【发布时间】:2019-02-22 06:01:45 【问题描述】:

比如在这个sn -p beg & end 中,好像被用作指针。然而在函数声明 In *beg 中,In *end 既不提供也不被 c++ 编译器接受。为什么我们像指针一样使用它而不像函数的指针参数一样声明它?

#include <vector>
#include <algorithm>
#include <iostream>
#include <iterator>
using namespace std;

template<class In, class X> void myreplace (In beg, In end, const X& x, const X& y)

    while (beg != end)
    
        if (*beg == x) *beg = y;
        beg++;
    


int main()

    vector<int> veca =  1, 3, 4, 4, 1, 4, 4 ;
    myreplace(veca.begin(), veca.end(), 4, 2);
    copy(veca.begin(), veca.end(), ostream_iterator<int>(cout, ","));

【问题讨论】:

迭代器是用于迭代它们所属的底层容器的抽象。由于它们以特定于容器的顺序指向元素,因此它们被用作指针。否则,它们就是对象。 迭代器概念的重点在于,您可以抽象出如何迭代集合的关注点,而只依赖于标准暴露的迭代器方法。 【参考方案1】:

Iterators 通常不仅仅是指针,而是指针的抽象。

根据他们的general requirements:

它们的语义是 C++ 中大多数指针语义的概括。这确保 每个带有迭代器的函数模板都可以与 常规指针

所以你也可以这样做:

myreplace(&veca[0], &veca[6], 4, 2);

其中&amp;veca[0]&amp;veca[6] 是指向向量veca 的第一个和最后一个元素的指针。

这是可能的,因为 [] operator 返回对指定位置元素的引用。

【讨论】:

【参考方案2】:

可以通过重载一元operator* 函数为任何使用定义的类型定义解引用运算符。

veca.begin()返回的类型就是这样的类型。可以使用 * 运算符取消引用该类型的对象。

标准库中大多数容器的begin() 成员函数返回的迭代器都支持这样的操作。因此您可以使用:

std::vector<int> a = 10, 20, 30;
std::vector<int>::iterator iter = a.begin();
int item = *iter;

std::set<int> a = 10, 20, 30;
std::set<int>::iterator iter = a.begin();
int item = *iter;

std::map<int, double> a = 10, 2.5, 20, 5.8;
std::map<int, double>::iterator iter = a.begin();
std::pair<int, double> item = *iter;

【讨论】:

【参考方案3】:

没有什么能阻止您将指针传递给myreplace。例如在通话中

int Carray[7] =  1, 3, 4, 4, 1, 4, 4 ;
myreplace(Carray, Carray + 7, 4, 2);

模板参数In推导为int *X推导为int。就像你写的一样

void myreplace (int * beg, int * end, const int & x, const int & y)

    while (beg != end)
    
        if (*beg == x) *beg = y;
        beg++;
    

接受行为足够类似指针的非指针(即模型InputIterator)

【讨论】:

【参考方案4】:

你的意思是正确的代码如下:

template<class In, class X> void myreplace (In* beg, In* end, const X& x, const X& y)

    while (*beg != *end)
    
        if (**beg == x) **beg = y;
        *beg++;
    

我认为首先你应该了解C++中的基本模板知识,事实上,在STL中,迭代器被定义为指针,但这并不意味着指针类型是迭代器的唯一类型

typedef T* iterator;

【讨论】:

以上是关于为啥 c++ 顺序访问迭代器的函数签名不使用指针?的主要内容,如果未能解决你的问题,请参考以下文章

c++中迭代器的问题为啥这样会报错?

C++ 的STL中,迭代器那个指针为何++能指向下一个元素?

C++迭代器 iterator

C++迭代器 iterator

C++ 迭代器iterator的实现原理

C++中的迭代器