【问题标题】:std::vector erase issue with MSVC 2010MSVC 2010 的 std::vector 擦除问题
【发布时间】:2018-12-05 16:29:24
【问题描述】:

所有,

我定义了一个只保存数据(不同类型的数据)的类。我还有 std::vector ,它包含指向此类对象的指针。

类似这样的:

class Foo
{
};

class Bar
{
private:
    std::vector<Foo *> m_fooVector;
};

在我的程序中的某个时间点,我想从这个向量中删除一个元素。所以我写了以下内容:

for (std::vector<Foo *>::iterator it = m_fooVector.begin(); it <= m_fooVector.end(); )
{
    if( checking it condition is true )
    {
        delete (*it);
        (*it) = NULL;
        m_fooVector.erase( it );
    }
}

问题是擦除操作失败。当我打开调试器时,我仍然在向量中看到这个元素,当程序完成时它崩溃了,因为该元素在这里的一半。

在另一个函数中,我试图从向量中删除简单的 std::wstring 并且一切正常 - 字符串被删除并且向量的大小减小。

这种行为可能有什么问题?我当然可以尝试检查 MSVC 标准库中的擦除功能,但我什至不知道从哪里开始。

TIA!!!

【问题讨论】:

  • 我相信 MSVC 2010 支持 C++11 的 std::unique_ptr。您也许可以使用它并简化您的一些代码。

标签: visual-studio-2010 c++11 vector std erase


【解决方案1】:

你的循环不正确:

for (std::vector<Foo *>::iterator it = m_fooVector.begin(); it != m_fooVector.end(); )
{
    if (/*checking it condition is true*/)
    {
        delete *it;
        // *it = NULL; // Not needed
        it = m_fooVector.erase(it);
    } else {
        ++it;
    }
}

传统方式是erase-remove idiom,但由于你必须先调用delete(智能指针会避免这个问题),你可以使用std::partition而不是std::remove

auto it = std::partition(m_fooVector.begin(), m_fooVector.end(), ShouldBeKeptFunc);
for (std::vector<Foo *>::iterator it = m_fooVector.begin(); it != m_fooVector.end(); ++it) {
    delete *it;
}
m_fooVector.erase(it, m_fooVector.end());

【讨论】:

  • 只是好奇 - 使用 unique_ptr 会是什么样子? std::vector<:unique_ptr> >?还是我的语法有误? MSVC 2010 也完全支持这种类型的指针吗?我回家后会尝试更正代码...
  • 没有额外的括号:std::vector&lt;std::unique_ptr&lt;Foo&gt; &gt;。不确定 MSVC 2010 是否支持将其作为解决方案提出。
猜你喜欢
  • 1970-01-01
  • 2011-07-17
  • 2011-10-24
  • 1970-01-01
  • 2016-03-31
  • 1970-01-01
  • 1970-01-01
  • 2022-10-24
  • 2011-09-30
相关资源
最近更新 更多