我们的编码指南更喜欢const_iterator,因为它们比正常情况下快一点iterator.看起来编译器会在您使用时优化代码const_iterator.
这真的是对的吗?如果是的话,内部真正发生的事情会变得const_iterator更快吗?
编辑:我写了一个小测试来检查const_iteratorvs iterator,发现不同的结果:
对于迭代10,000个对象const_terator,花费几毫秒(大约16毫秒).但并非总是如此.有两次相等的迭代.
我需要知道如何将LinkedList迭代器"重置"到它的第一个元素.
例如:
LinkedList<String> list;
Iterator iter=list.listIterator;
iter.next();
iter.next();
一遍又一遍,经过迭代器的多次移动后,我需要"重置"迭代器的位置.`
我想问一下如何将我的迭代器"重置"到第一个元素
我知道我可以通过这种方式获得第一个元素的列表迭代器:
iter= list.listIterator(1);
这是最好的解决方案吗?或者我可能错过了Oracle文档中的某些内容?
假设您正在编写一个接受被std::initializer_list调用list的函数,并且该函数需要随机访问其list元素.写list[i]代替是方便的list.begin()[i].那么为什么不std::initializer_list提供定义operator[]呢?
我想不出任何operator[]返回const T&不明确的情况.效率在这里似乎不是问题,因为std::initializer_list<T>::iterator别名const T*,显然是随机访问迭代器.
我正在Windows和Mac之间编写一些跨平台代码.
如果list :: end()"返回一个迭代器来解决列表中最后一个元素之后的位置"并且可以在向前遍历列表时进行检查,那么向后遍历的最佳方法是什么?
此代码适用于Mac但不适用于Windows(不能超出第一个元素):
list<DVFGfxObj*>::iterator iter = m_Objs.end();
for (iter--; iter!=m_Objs.end(); iter--)// By accident discovered that the iterator is circular ?
{
}
Run Code Online (Sandbox Code Playgroud)
这适用于Windows:
list<DVFGfxObj*>::iterator iter = m_Objs.end();
do{
iter--;
} while (*iter != *m_Objs.begin());
Run Code Online (Sandbox Code Playgroud)
是否有另一种可以在for循环中实现的向后遍历方法?
标准中的§23.1.2.8声明对set/map的插入/删除操作不会使对这些对象的任何迭代器无效(指向已删除元素的迭代器除外).
现在,考虑以下情况:您希望实现具有唯一编号节点的图形,其中每个节点具有固定数量(假设4个)邻居.利用上述规则,你可以这样做:
class Node {
private:
// iterators to neighboring nodes
std::map<int, Node>::iterator neighbors[4];
friend class Graph;
};
class Graph {
private:
std::map<int, Node> nodes;
};
Run Code Online (Sandbox Code Playgroud)
(编辑:由于Node第4行的不完整性(参见回复/评论),并非字面意思,但无论如何都沿着这些方向)
这很好,因为这样您就可以插入和删除节点而不会使结构的一致性失效(假设您跟踪删除并从每个节点的数组中删除已删除的迭代器).
但是,假设您还希望能够存储"无效"或"不存在"的邻居值.不用担心,我们可以使用nodes.end()...或者我们可以吗?是否存在某种保证,nodes.end()在nodes.end()经过多次插入/删除后,上午8点将与下午10点相同?也就是说,我可以安全地==将作为参数接收的迭代器nodes.end()与Graph的某些方法进行比较吗?
如果没有,这会有效吗?
class Graph {
private:
std::map<int, Node> nodes;
std::map<int, Node>::iterator _INVALID;
public:
Graph() { _INVALID = nodes.end(); }
};
Run Code Online (Sandbox Code Playgroud)
也就是说,我可以nodes.end()在构造时存储变量,然后每当我想将邻居设置为无效状态时使用此变量,或者将它与方法中的参数进行比较吗?或者有可能在某个地方,指向现有对象的有效迭代器将比较等于_INVALID?
如果这也不行,有什么可怎么办留有余地无效邻居价值?
我正在阅读" 我们是否需要在ArrayList上使用迭代器? " 这一问题中提到的答案.
在答案中,用户声明了这样的话:"使用ArrayLists的迭代器的一个大用例是当你想在迭代时删除元素".
即使在Java中使用ArrayList的remove方法也可以实现这一点.我的问题是为什么我们需要ArrayList中的迭代器?
考虑一下代码:
import java.util.*;
public class ocajp66 {
public static void main(String[] args) {
ArrayList a = new ArrayList();
for (int i = 0; i < 10; i++) {
a.add(i);
}
System.out.printf("BEFORE ITERATOR\n");
for (int i = 0; i < a.size(); i++) {
System.out.printf("I:%d\n", a.get(i));
}
System.out.printf("AFTER ITERATOR\n");
Iterator i = a.iterator();
while (i.hasNext()) {
System.out.printf("I:%d\n", i.next());
}
}
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释迭代器的重要性吗?如果你能用代码解释我会很棒.
我看到它引用了很多,但没有明确的答案,究竟是什么.我的经验是使用更高级别的语言,所以我不熟悉集合框架中存在的无效性.
什么是迭代器失效?
为什么会出现?为什么难以处理?
我是c +的新手,并且正在努力弄清楚我应该如何迭代对象列表并访问那些成员.
我一直在尝试这里,'数据'是列表,'学生'是一个类.
std::list<Student>::iterator<Student> it;
for(it = data.begin(); it != data.end(); ++it){
std::cout<<(*it)->name;
}
Run Code Online (Sandbox Code Playgroud)
并得到以下错误
error: base operand of ‘->’ has non-pointer type ‘Student’
Run Code Online (Sandbox Code Playgroud) 假设我有一个
std::vector<int> v
//and ...
for(int i =0;i<100;++i)
v.push_back(i);
Run Code Online (Sandbox Code Playgroud)
现在我想要一个迭代器,让我们说矢量的第10个元素.
没有做以下方法
std::vector<int>::iterator vi;
vi = v.begin();
for(int i = 0;i<10;i++)
++vi;
Run Code Online (Sandbox Code Playgroud)
因为这将破坏向量的随机访问迭代器的优势.
我想用BOOST FOREACH复制以下内容
std::vector<int>::const_iterator i1;
std::vector<int>::const_iterator i2;
for( i1 = v1.begin(), i2 = v2.begin();
i1 < v1.end() && i2 < v2.end();
++i1, ++i2 )
{
doSomething( *i1, *i2 );
}
Run Code Online (Sandbox Code Playgroud)