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

时间:2019-02-22 06:01:46

标签: c++ pointers iterator

例如在此代码段的开头和结尾,似乎被用作指针。但是在函数声明中,* beg中,* 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, ","));
}

4 个答案:

答案 0 :(得分:1)

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

根据他们的general requirements

  

它们的语义是C ++中大多数指针语义的概括。这样可以确保每个使用迭代器的函数模板都可以正常工作   常规指针

因此,您也可以改为这样做:

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

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

之所以可行,是因为 [] operator返回对指定位置元素的引用。

答案 1 :(得分:0)

可以通过重载一元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;

答案 2 :(得分:0)

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

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

推论模板参数Inint *,推论Xint。就像你写的一样

void myreplace (int * beg, int * end, const int & x, const int & y)
{
    while (beg != end)
    {
        if (*beg == x) *beg = y;
        beg++;
    }
}

接受行为充分类似于指针的非指针(即模型InputIterator

答案 3 :(得分:-2)

您的意思是否正确,如下所示:

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;