使用带有c ++中的set的begin()和end()

时间:2011-08-29 21:30:18

标签: c++ set stdvector stdset

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

感兴趣的代码段是:

    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,程序正常运行。

P.S。命令verlet_vars.verlet()[i]调用集合的向量,因此[i]

verlet()函数:

std::vector<std::set<int> > verlet() const {return _verlet;}

感谢您的时间。

2 个答案:

答案 0 :(得分:8)

您的verlet_vars.verlet()函数按值返回,因此您实际上有两个不同的集合向量。 Comparing iterators of two different containers is undefined.这意味着某些代码安排似乎总是有效,但如果确实如此,你仍然很幸运。

一些替代方案:

  • 使函数返回向量引用:

    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++)
    

答案 1 :(得分:0)

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