C ++:无法将索引分配给迭代器
Posted
技术标签:
【中文标题】C ++:无法将索引分配给迭代器【英文标题】:C++: cannot assign index to iterator 【发布时间】:2016-10-26 21:37:06 【问题描述】:好的,一个小问题,希望有一个快速、简单的解决方案。
在我的课本中,在关于 STL 的一章中,它提供了一个简单的示例程序,用于输入使用列表和使用带有列表的迭代器,如下所示:
#include <list>
#include <iostream>
#include <string>
using namespace std;
int main()
list<int> myIntList;
// Insert to the front of the list.
myIntList.push_front(4);
myIntList.push_front(3);
myIntList.push_front(2);
myIntList.push_front(1);
// Insert to the back of the list.
myIntList.push_back(5);
myIntList.push_back(7);
myIntList.push_back(8);
myIntList.push_back(9);
// Forgot to add 6 to the list, insert before 7. But first
// we must get an iterator that refers to the position
// we want to insert 6 at. So do a quick linear search
// of the list to find that position.
list<int>::iterator i = 0;
for( i = myIntList.begin(); i != myIntList.end(); ++i )
if( *i == 7 ) break;
// Insert 6 were 7 is (the iterator I refers to the position
// that 7 is located. This does not overwrite 7; rather it
// inserts 6 between 5 and 7.
myIntList.insert(i, 6);
// Print the list to the console window.
for( i = myIntList.begin(); i != myIntList.end(); ++i )
cout << *i << " "; cout << endl;
现在,在上面写着的那一行
list<int>::iterator i = 0;
我在 VS 2015 中收到一条错误消息:
no suitable constructor exists to convert from"int" to "std::_List_iterator<std::_List_val<std::_List simple_types<int>>>"
提供的代码有什么问题,解决方案是什么,为什么会出现这个问题?
【问题讨论】:
“在我的学校教科书中”哇。 Consider getting a better one.std::list
没有随机访问迭代器,例如std::vector
如果学校教科书有这行:listvector<int>::iterator i = 0
”)也无法使用
天哪,伙计们,这只是一个错字,我认为这不值得“买一本更好的书”cmets,尤其是因为我们甚至不知道实际使用的是什么书。只需从迭代器声明中删除 = 0
并继续。
【参考方案1】:
值0
可能不是迭代器的有效值。尝试删除分配或将迭代器分配给myIntList.begin()
。
迭代器可能无法被视为索引,例如vector
或数组。通常链表不通过索引访问;你必须从头开始遍历。
【讨论】:
你是对的,但是,你没有解释为什么0
可能不是迭代器的有效值。如果我没记错的话,是不是因为 std::list
没有随机访问迭代器,这与例如std::vector
?
据我所知,整数不是(任何)迭代器的有效值,因为要构造迭代器,您需要以某种方式引用原始结构(从中获取迭代器) .这显然不是简单整数的情况。 (或者当然没有参数,你会创建一个无效的空迭代器)
可能没有采用整数值的构造函数或赋值运算符。
根据cppreference.com,std::list::iterator
只需满足双向迭代器接口即可。
本书中的代码可能已经在旧的编译器和库上进行了测试,其中 list::iterator 是某种指针的 typedef。在这种情况下,0 就可以了,并且是空指针的同义词。【参考方案2】:
提供的代码有什么问题
示例中有一个简单的错字。
解决办法是什么
替换这一行:
list<int>::iterator i = 0;
用这个代替:
list<int>::iterator i;
为什么会出现这个问题?
您不能使用整数值初始化迭代器。只有容器知道它的迭代器指的是什么,所以只有容器可以初始化它们。您所能做的就是从容器中请求一个迭代器,将一个迭代器分配给另一个迭代器,然后递增/递减/取消引用一个迭代器。就是这样。
【讨论】:
【参考方案3】:来自http://www.cplusplus.com/reference/iterator/:
迭代器是任何对象,它指向元素范围(例如数组或容器)中的某个元素,能够使用一组运算符(至少具有递增 (++) 和取消引用 (*) 运算符)。
这意味着迭代器应该能够执行以下操作:
-
返回当前“指向”的对象(使用
*
运算符)
将自身更改为“指向”其列表中的下一个对象(使用++
运算符)
迭代器作为数据类型存在的一个原因是创建一种与不同类型列表交互的通用方式。然而,这意味着不同的列表会以不同的方式实现它们的迭代器。
在许多情况下,将迭代器初始化为数字是没有意义的,因为它是在后台实现的。因此,我们没有定义一个赋值运算符,我们的迭代器类型 std::vector<int>::iterator
在左边,int
在右边。因此,当您尝试将迭代器分配给整数值时,list<int>::iterator i = 0;
您的编译器会抛出错误。
让我们看一个将迭代器分配给0
没有意义的示例。您可以将 std::vector<int>
的迭代器实现为指向向量中元素的指针。在这种情况下:
*
取消引用存储在 vector<int>::iterator
中的指针并返回其值。
++
将vector<int>::iterator
中存储的指针修改为指向列表中的下一个 元素。
但是,将此指针分配给0
与将其分配给NULL
相同,并且取消引用它不再返回向量中的有效元素。 (其实取消引用NULL
会报错!)
为避免此错误,只需确保始终将迭代器分配给相同类型的值。在 STL 中,这通常通过使用 .begin()
返回一个指向列表中第一个元素的迭代器来完成。
【讨论】:
以上是关于C ++:无法将索引分配给迭代器的主要内容,如果未能解决你的问题,请参考以下文章
为什么迭代器只能被一个集合使用呢 为什么迭代器不能在迭代过程中 ?增删呢 是因为 每次迭代时候 把之前的元素给拿出去了 如果你在操作过程中将下一个迭代元素给拿走了(迭代器不具备自动判断长度功能 她依旧