【问题标题】:Adding an element to a Vector while iterating over it迭代时将元素添加到 Vector
【发布时间】:2016-06-18 18:05:25
【问题描述】:

正如标题所说,在某些情况下,我想在遍历向量时向std::vector 添加一个元素。使用以下代码,我收到错误“调试断言失败”。有没有可能实现我想做的事情?

这是我测试过的代码:

#include <vector>

class MyClass
{
public:
    MyClass(char t_name)
    {
        name = t_name;
    }
    ~MyClass()
    {
    }
    char name;
};

int main()
{
    std::vector<MyClass> myVector;
    myVector.push_back(MyClass('1'));
    myVector.push_back(MyClass('2'));
    myVector.push_back(MyClass('3'));

    for each (MyClass t_class in myVector)
    {
        if (t_class.name == '2')
             myVector.push_back(MyClass('4'));
    }
    return 0;
}

编辑:

好吧,我认为for each 是标准 C++,但它似乎是 Visual Studio 的功能:

for each, in

Visual c++ "for each" portability

【问题讨论】:

  • for each (MyClass t_class in myVector) 这是 c++ 吗??
  • 那不是有效的 c++ 代码!
  • 别介意这种不确定的语法,在迭代向量时将元素插入向量是没有意义的,因为push_back 可能会使所有现有的迭代器失效。
  • @foreknownas_463035818 #define in : 现在是

标签: c++ vector foreach


【解决方案1】:

std::vector 中添加或删除项目的行为会使现有的迭代器无效。因此,您不能使用任何依赖迭代器的循环,例如for each, inrange-based forstd::for_each() 等。您必须使用索引进行循环,例如:

int main()
{
    std::vector<MyClass> myVector;

    myVector.push_back('1');
    myVector.push_back('2');
    myVector.push_back('3');

    std::vector<MyClass>::size_type size = myVector.size();
    for (std::vector<MyClass>::size_type i = 0; i < size; ++i)
    {
        if (myVector[i].name == '2')
        {
             myVector.push_back('4');
             ++size; // <-- remove this if you want to stop when you reach the new items
        }
    }

    return 0;
}

【讨论】:

  • 为什么要设置大小变量? i &lt; myVector.size()works too
  • @bb1950328 这样做会在每次迭代中强制对size()进行函数调用,而在使用变量时,在循环之前只有一个对size()的函数调用被输入。如果size() 是内联的,那么这两种方式都可能无关紧要,但如果size() 没有内联,那么如果向量大小很大,性能可能会受到影响。更重要的是,您的方法不允许循环在到达旧项目的末尾时停止,因为您知道没有一个新项目与正在测试的条件匹配。
  • 有道理,感谢您的澄清
【解决方案2】:

正如 pyon 所指出的,在迭代向量时(通过迭代器)将元素插入向量是行不通的,因为插入元素会使迭代器失效。但是,您似乎只想将元素推到向量的后面。这可以在不使用迭代器的情况下完成,但您应该小心停止条件:

std::vector<MyClass> myVector;
size_t old_size = myVector.size();
for  (int i=0;i<old_size;i++) {
    if (myVector[i].name == '2') { myVector.push_back(MyClass('4')); }
}

【讨论】:

    【解决方案3】:

    按照前面的答案,您可以使用const auto&amp;auto&amp; 来获得干净 代码。应该由编译器在发布版本中进行优化。

    std::vector<MyClass> myVector;
    std::vector<MyClass>::size_type size = myVector.size();
    for (std::vector<MyClass>::size_type i = 0; i < size; ++i)
    {
        const auto& element = myVector[i];
        element.do_stuff();
    }
    

    【讨论】:

      猜你喜欢
      • 2020-04-22
      • 2023-04-02
      • 2012-07-22
      • 2012-05-08
      • 2016-11-30
      • 2014-10-28
      • 2015-02-07
      • 2021-12-02
      • 1970-01-01
      相关资源
      最近更新 更多