将向量迭代器传递给C++函数

14

有人能解释一下为什么下面的代码段可以编译通过,但是注释掉的那一行却不行吗?

struct tObj
{
    int data;
    int moreData;
}

...

void funcToCall (tObj *obj, int moreData)
{
    //Useful stuff here
}

void mainFunction ()
{
    vector<tObj>::iterator it = vectorOfObjects.begin(); //assumes vectorOfObjects is already defined
    while (it != vectorOfObjects.end())
    {
        funcToCall (&(*it), 0); //This line works
        funcToCall (it, 0); //This line produces an error
        it++;
    }
}

生成的错误信息如下:

error: cannot convert ‘std::vector<tObj>::iterator {aka __gnu_cxx::__normal_iterator<tObj*, std::vector<tObj> >}’ to ‘tObj*’

你有没有想过为什么 &(*it) 可以工作,但是只用 it 就不行呢?从逻辑上讲,它们不是相同的吗?

因为 * 的意思是解引用,& 的意思是通过引用传递,也就是互相抵消了。


2
该函数期望一个指向tObj的指针,而你传递了一个迭代器。虽然某些实现可能将vector<T>::iterator实现为T*,但迭代器并不是指针。 - juanchopanza
2个回答

15

it是一个迭代器对象,直接传递它将意味着你试图将一个vector<tObj>::iterator类型的对象传递给一个预期接受tObj*类型参数的函数,因此会出现错误。

当你使用*it时,你将得到迭代器所表示的基础对象,而当你在其上应用&操作符时,你将得到该对象的地址,该地址的类型为tObj*,与函数的参数类型相符,因此不会出错。


啊,谢谢你的提示。我想向量迭代器对我来说只是很困惑的。 - Tim
3
也许吧,但是把迭代器仅仅看作是这样——不是指针,不是其他什么。它们只是允许你以某种方式遍历集合。这些迭代器提供了一个operator*来访问底层元素,与指针无关;这只是一种语法糖。 - legends2k
这让我更加明白了。非常感谢您提供的信息。我甚至没有想到他们可能会重载 operator* - Tim

7

如果您想要编译代码,需要声明一个重载函数,例如:

void funcToCall ( std::vector<tObj>::iterator it, int moreData)
{
    //Useful stuff here
}

通常情况下,类型tObj *vector<tObj>::iterator是不同的类型,尽管在一些旧版本的std::vector中,其迭代器确实定义为指针。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接