是否可以从带有C++ 11 for for循环的向量中擦除?

Mol*_*lma 1 c++ for-loop vector erase c++11

好的.为了其他(更简单但不够解释)问题,这可能看起来像,我不是在问这是可能的还是不可能的(因为我已经发现了),我在问我是否有更轻松的替代品题.

我所拥有的是主要类,在主类中,有一个引用"世界地图"类的变量.实质上,这个"WorldMap"类是其他类变量的容器.主类完成所有循环并更新所有相应的活动对象.在这个循环中,我需要删除一个向量的对象,该对象位于递归容器集的深处(如提供的代码所示).重复必须将必要的变量作为指向另一个指针(等等)的指针引用我需要的特定对象,然后将其删除(这是我在切换到C++之前使用的概念)将是非常繁琐的. 11)所以我有一个循环范围(也在代码中显示).我的示例代码显示了我已经到位的想法,我希望减少单调乏味以及使代码更具可读性.

这是示例代码:

struct item{
    int stat;
};

struct character{
    int otherStat;
    std::vector<item> myItems;
};

struct charContainer{
    std::map<int, character> myChars;
};

int main(){
    //...
    charContainer box;
    //I want to do something closer to this
    for(item targItem: box.myChars[iter].myItems){
        //Then I only have to use targItem as the reference
        if(targItem.isFinished)
            box.myChars[iter].myItems.erase(targItem);
    }
    //Instead of doing this
    for(int a=0;a<box.myChars[iter].myItems.size();a++){
        //Then I have to repeatedly use box.myChars[iter].myItems[a]
        if(box.myChars[iter].myItems[a].isFinished)
            box.myChars[iter].myItems.erase(box.myChars[iter].myItems[a]);
    }
}
Run Code Online (Sandbox Code Playgroud)

TLDR:我想通过使用C++ 11中显示的新的循环范围来消除重复调用完整引用的繁琐.

编辑:我不是想一次删除所有元素.我问我如何在第一个循环中删除它们.当我在外部完成它们时(通过if语句),我将删除它们.我如何删除特定元素,而不是所有元素?

Sva*_*zen 7

如果您只想清除std :: vector,可以使用一种非常简单的方法:

std::vector<item> v;

// Fill v with elements...

v.clear(); // Removes all elements from v.
Run Code Online (Sandbox Code Playgroud)

除此之外,我想指出[1]擦除向量中的元素需要使用迭代器,[2]即使你的方法被允许,从for循环中的向量中擦除元素也是如此.如果你不小心,这是一个坏主意.假设你的向量有5个元素:

std::vector<int> v = { 1, 2, 3, 4, 5 };
Run Code Online (Sandbox Code Playgroud)

然后你的循环将具有以下效果:

  • 第一次迭代: a == 0, size() == 5.我们删除第一个元素,然后向量将包含{2, 3, 4, 5}

  • 第二次迭代: a == 1, size() == 4.然后我们删除第二个元素,然后向量将包含{2,4,5}

  • 第三次迭代: a == 2, size() == 3.我们删除了第三个元素,我们留下了最终结果{2,4}.

由于这实际上并没有清空向量,我想这不是你想要的.

如果你有一些特殊条件想要应用于删除元素,那么它很容易在C++ 11中以下列方式应用:

std::vector<MyType> v = { /* initialize vector */ };

// The following is a lambda, which is a function you can store in a variable.
// Here we use it to represent the condition that should be used to remove
// elements from the vector v.
auto isToRemove = [](const MyType & value){ 
    return /* true if to remove, false if not */ 
};

// A vector can remove multiple elements at the same time using its method erase().
// Erase will remove all elements within a specified range. We use this method 
// together with another method provided by the standard library: remove_if.
// What it does is it deletes all elements for which a particular predicate 
// returns true within a range, and leaves the empty spaces at the end.
v.erase( std::remove_if( std::begin(v), std::end(v), isToRemove ), std::end(v) );

// Done!
Run Code Online (Sandbox Code Playgroud)