1

我正在尝试使用迭代器来遍历一个集合,然后对该集合的成员执行某些操作(如果有的话)。问题是,通常这是可行的,但有时,它会比较空集的开头和结尾,发现它们不相等。

感兴趣的代码片段是:

    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;}

谢谢你的时间。

4

2 回答 2

8

您的verlet_vars.verlet()函数按值返回,因此您实际上有两个不同的集合向量。比较两个不同容器的迭代器是未定义的。这意味着某些代码安排可能看起来总是有效,但如果确实如此,您仍然很幸运。

一些替代方案:

  • 使函数返回一个向量引用:

    std::vector<std::set<int> > const& verlet() const {return _verlet;}
    
  • 调用该函数一次以获取向量(或集合)的本地副本,然后在循环期间处理本地副本:

    std::set<int> verlet_i = verlet_vars.verlet()[i];
    set<int>::iterator iter;
    for(iter=verlet_i.begin();iter!=verlet_i.end();iter++)
    
于 2011-08-29T21:40:06.110 回答
0

它可能并不重要,具体取决于您的编译器是否复制返回值。您应该在 . 的返回类型上使用 const 引用verlet()。如果不是,您最终可能会在每次调用时收到不同的副本,这(取决于实现)可能会导致迭代器没有被精确比较(例如,将一个集合的迭代器与另一个集合的结束迭代器进行比较,因为每个当你打电话给你时,verlet()你会得到一套不同的副本。)

于 2011-08-29T21:42:44.043 回答