【问题标题】:C++ remove_if on a vector of objects对象向量上的 C++ remove_if
【发布时间】:2011-10-31 18:49:26
【问题描述】:

我有一个对象向量(顺序很重要)(我们称它们为 myobj 类),我试图一次删除多个对象。

class vectorList
{

    vector<*myobj> myList; 
};

class myobj
{

    char* myName;
    int index;
    bool m_bMarkedDelete;
}

我认为最好的方法是标记特定的 myobj 对象以进行删除,然后在向量上调用 myList.remove_if()。但是,我不确定如何为此使用谓词等。我是否应该在对象中创建一个成员变量,让我说我想删除 myobj,然后创建一个谓词来检查是否设置了成员变量?

如何将谓词实现为 vectorList 类的一部分?

【问题讨论】:

  • 它可能不相关,但 std::list 保留顺序并具有自己的 remove_if 函数,该函数更快且不需要单独擦除。
  • @Ant: list::remove_if 比删除和擦除矢量更快?在什么情况下?在我做过的许多合理的测试中,情况肯定不是这样。不要仅仅因为擦除是列表的恒定时间操作就认为它会更快。 std::vector 的连续性和随机访问保证为其带来了极大的性能。

标签: c++ vector stl predicate


【解决方案1】:

我应该在对象中创建一个允许我说的成员变量吗 我想删除 myobj 然后创建一个谓词 检查是否设置了成员变量?

你还没有这样做吗?这不是m_bMarkedDelete 的用途吗?你可以这样写谓词:

bool IsMarkedToDelete(const myobj & o)
{
    return o.m_bMarkedDelete;
}

然后:

myList.erase(
    std::remove_if(myList.begin(), myList.end(), IsMarkedToDelete),
    myList.end());

或者,使用 lambda:

myList.erase(
    std::remove_if(myList.begin(), myList.end(),
        [](const myobj & o) { return o.m_bMarkedDelete; }),
    myList.end());

如果您的班级实际上没有该成员,并且您问我们是否应该这样做,那么我会拒绝。您使用什么标准来决定将其标记为删除?在您的谓词中使用相同的标准,例如:

bool IndexGreaterThanTen(const myobj & o)
{
    return o.index > 10;
}

note -- 我写的函数当然是无效的,因为你所有的成员都是私有的。所以你需要一些方法来访问它们。

【讨论】:

  • 我收到以下错误,因为它是一个指针:错误 C2662:'myobj::IsMarkedToDelete':无法将 'this' 指针从 'const myobj' 转换为 'myobj &。我将其标记为删除,因为我是从一个具有与我的向量同步的网格的类中进行的。我必须删除网格中的行,然后删除向量中相应的选定行。
  • @Jordan:不应该是会员,应该是免费功能。
  • IsMarkedToDelete 应该是免费功能吗?似乎问题出在对象的“常量性”上......
  • @Jordan:这是关于this 指针。不应该有this 指针,因为这个函数不应该是成员。
  • IsMarkedToDelete 应该是静态函数
【解决方案2】:

谓词基本上是一个条件比较。它可以是函数或对象。这是一个使用新 C++ lambda 的示例。此代码将遍历向量并删除等于 3 的值。

int arg[6] = {1, 2, 3, 3, 3, 5};
std::vector<int> vec(arg, arg+6);
vec.erase(
   std::remove_if(
      vec.begin(), vec.end(),
      [](int i){ return i == 3;}),
   vec.end());

编辑:对于指针,假设您有一个向量或接口,您可以将它们设置为nullptr,然后使用几乎相同的代码批量删除它们。在 VS2008 中,您将没有 lambda,因此请改为使用比较谓词函数或结构。

bool ShouldDelete(IAbstractBase* i)
{
    return i == nullptr;
    // you can put whatever you want here like:
    // return i->m_bMarkedDelete;
}

std::vector<IAbstractBase*> vec;
vec.erase(
   std::remove_if(
      vec.begin(), vec.end(),
      ShouldDelete),
   vec.end());

【讨论】:

  • 如果向量是 myobj* 指针列表,我该怎么做?这是我感到困惑的事情之一。这将在 VS 2008 中工作吗?谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-01
  • 2011-02-11
  • 1970-01-01
相关资源
最近更新 更多