如何在C++中擦除vector中的条目?

use*_*729 4 c++ windows vector

我基本上循环遍历所有条目以检查是否要删除某些条目,但似乎是错误的方式:

std::vector<HANDLE> myvector; 
for(unsigned int i = 0; i < myvector.size(); i++)
{
    if(...)
         myvector.erase(myvector.begin()+i);
}
Run Code Online (Sandbox Code Playgroud)

有人发现了它的问题吗?怎么做正确?

GMa*_*ckG 8

你可以用std::remove_if.这会将所有剩余元素移到前面,并将迭代器返回到新的后面.然后你可以删除它:

struct my_predicate
{
    bool operator()(HANDLE) const
    {
        return ...;
    }
};

typedef std::vector<HANDLE> vector_type;

vector_type::iterator newEnd =
    std::remove_if(myvector.begin(), myvector.end(), my_predicate());

myvector.erase(newEnd, myvector.end());
Run Code Online (Sandbox Code Playgroud)

它通常在一条线上完成.如果你的编译器支持lambda(C++ 0x),你可以这样做:

vector_type::iterator newEnd =
    std::remove_if(myvector.begin(), myvector.end(), [](HANDLE){ return ... });

myvector.erase(newEnd, myvector.end());
Run Code Online (Sandbox Code Playgroud)

保持谓词本地化.


如果你觉得这很难看,那就把它包起来:

template <typename Vec, typename Pred>
Pred erase_if(Vec& pVec, Pred pPred)
{
    pVec.erase(std::remove_if(pVec.begin(), pVec.end(),
                                pPred), pVec.end());

    return pPred;
}
Run Code Online (Sandbox Code Playgroud)

然后:

erase_if(myvector, mypredicate);
Run Code Online (Sandbox Code Playgroud)

当然,C++ 0x lambda的工作原理相同.