我正在尝试使用迭代器来遍历一个集合,然后对该集合的成员(如果有的话)执行一些操作。问题是,通常这是可行的,但有时,它会比较空集的开头和结尾,发现它们不相等。
感兴趣的代码片段是:
for(int i=0;i<input_data.num_particles();i++)
{
//loop through pairs contained in particle i's Verlet list
set<int>::iterator iter;
for(iter=verlet_vars.verlet()[i].begin();iter!=verlet_vars.verlet()[i].end();iter++)
{
//call the force() function to calculate the force between the particles
force(particles.getpart(i),particles.getpart(*iter),input_data,*iter);
}
}
有时,即使 verlet_vars.verlet()[i] 中包含的集合为空,程序也会将迭代器与集合的末尾进行比较,发现它们不相等,因此进入内循环(最终通过尝试调用force()函数导致程序崩溃)。奇怪的是,如果我在调用内部循环之前对迭代器执行任何操作,例如执行以下操作:
iter=verlet_vars.verlet()[i].begin();
那么,内部循环的比较总是返回 true,并且程序正常运行。
PS 命令 verlet_vars.verlet()[i] 调用集合向量,因此 [i]
verlet() 函数:
std::vector<std::set<int> > verlet() const {return _verlet;}
感谢您的宝贵时间。
I am trying use an iterator to go through a set and then do something with the members of that set(if there are any). The problem is that, normally this works, but sometimes, it compares the beginning and the end of an empty set and finds them not to be equal.
The code snippet of interest is:
for(int i=0;i<input_data.num_particles();i++)
{
//loop through pairs contained in particle i's Verlet list
set<int>::iterator iter;
for(iter=verlet_vars.verlet()[i].begin();iter!=verlet_vars.verlet()[i].end();iter++)
{
//call the force() function to calculate the force between the particles
force(particles.getpart(i),particles.getpart(*iter),input_data,*iter);
}
}
Sometimes, even though the set contained in verlet_vars.verlet()[i] is empty, the program compares the iterator to the end of the set and finds them not equal, and so it enters the inner loop(ultimately causing the program to crash by trying to call the force() function). What is bizarre is if I do anything with the iterator before the inner loop is called,like doing something like:
iter=verlet_vars.verlet()[i].begin();
then, the comparison for the inner loop always returns true, and the program runs normally.
P.S. the command verlet_vars.verlet()[i] calls a vector of sets, hence the [i]
The verlet() function:
std::vector<std::set<int> > verlet() const {return _verlet;}
Thanks for your time.
发布评论
评论(2)
您的
verlet_vars.verlet()
函数按值返回,因此您实际上有两个不同的集合向量。 比较两个不同容器的迭代器是未定义的。这意味着某些代码安排是可能的看起来总是有效,但如果有效的话,你仍然很幸运。一些替代方案:
使函数返回向量引用:
调用该函数一次以获取向量(或集合)的本地副本,然后在循环期间处理本地副本:
Your
verlet_vars.verlet()
function returns by value, so you actually have two different vectors of sets in play. Comparing iterators of two different containers is undefined. That means it's possible for some arrangements of code to appear to always work, but you're still just lucky if it does.Some alternatives:
Make the function return a vector reference instead:
Call the function once to get a local copy of the vector (or the set) and then work off the local copy during the loop:
这可能并不重要,具体取决于您的编译器是否复制返回值。您应该在
verlet()
的返回类型上使用 const 引用。如果不是,您可能最终会在每次调用时收到不同的副本,这(取决于实现)可能会导致迭代器无法精确比较(例如,将一个集合的迭代器与另一个集合的结束迭代器进行比较,因为每个当你调用verlet()
时,你会得到该集合的另一个副本。)It may not be of importance, depending on whether your compiler does copy or not the returning value. You should be using a const reference on the return type of
verlet()
. If not, you may end up receiving a different copy with each call, that (depending on the implementation) may cause the iterators not being compared exactly (for instance, comparing an iterator of a set with the end iterator of another set, because each time you callverlet()
you get a different copy of the set.)