迭代的正确方法是使用迭代器.但是,我认为通过擦除,迭代器无效.
基本上我想做的是:
for(iterator it = begin; it != end; ++it)
{
    if(it->somecondition() )
    {
     erase it
    }
}
没有v [i]方法我怎么能这样做?
谢谢
struct RemoveTimedEvent
{
    bool operator()(const AguiTimedEvent& pX, AguiWidgetBase* widget) const 
    {
        return pX.getCaller() == widget;
    }
};
void AguiWidgetContainer::clearTimedEvents( AguiWidgetBase* widget )
{
    std::vector<AguiTimedEvent>::iterator it = std::remove_if(timedEvents.begin(),
        timedEvents.end(), RemoveTimedEvent());
    timedEvents.erase(it, timedEvents.end());
}
GMa*_*ckG 49
erase() 返回一个新的迭代器:
for(iterator it = begin; it != end(container) /* !!! */;)
{
    if (it->somecondition())
    {
        it = vec.erase(it);  // Returns the new iterator to continue from.
    }
    else
    {
        ++it;
    }
}
请注意,我们无法再将其与预先计算的结果进行比较,因为我们可能会将其删除,从而使其无效.我们必须每次都明确地结束.
一个更好的方法可能是结合std::remove_if和erase().你从O(N 2)(每个元素被擦除并随着你移动)变为O(N):
iterator it = std::remove_if(begin, end, pred);
vec.erase(it, vec.end());
pred你的删除谓词在哪里,例如:
struct predicate // do choose a better name
{
    bool operator()(const T& pX) const // replace T with your type
    {
        return pX.shouldIBeRemoved();
    }
};
iterator it = std::remove_if(begin, end, predicate());
vec.erase(it, vec.end());
在你的情况下,你可以使它非常一般:
class remove_by_caller
{
public:
    remove_by_caller(AguiWidgetBase* pWidget) :
    mWidget(pWidget)
    {}
    // if every thing that has getCaller has a base, use that instead
    template <typename T> // for now a template
    bool operator()(const T& pX) const
    {
        return pX.getCaller() == mWidget;
    }
private:
    AguiWidgetBase* mWidget;
};
std::vector<AguiTimedEvent>::iterator it =
    std::remove_if(timedEvents.begin(), timedEvents.end(), remove_by_caller(widget));
timedEvents.erase(it, timedEvents.end());
注意在Boost和C++ 11中都存在lambda来简化这个过程.
| 归档时间: | 
 | 
| 查看次数: | 9439 次 | 
| 最近记录: |