【问题标题】:Can't remove element by ID from vector of non primitive datatypes无法从非原始数据类型的向量中按 ID 删除元素
【发布时间】:2026-01-20 05:40:01
【问题描述】:

我有一个用户定义数据类型city 的向量。我试图通过它的 ID 从这个向量中删除一个元素;最终,所有城市都将在while(!cityList.empty()) 循环中从此列表中删除。我打算使用erase-remove 成语来完成此操作。

但是,当我在调用remove()制作我的代码时,我收到了一条非常粗糙的错误消息。将 city 对象作为第三个参数传递给 remove() 会导致此错误,传递 city 的 (int) ID 也是如此。 erase() 不会发生此错误,但 remove() 会发生此错误,如果我尝试使用它,find() 也会发生此错误。这是有问题的代码:

vector<city> cityList;
cityList.push_back(city(1));
cityList.push_back(city(2));
cityList.push_back(city(3));

city cityToRemove = cityList[0];
int idOfCityToRemove = cityList[0].getID();

remove(cityList.begin(), cityList.end(), cityToRemove);
//remove(cityList.begin(), cityList.end(), idOfCityToRemove);

Here is an updated simple, minimal demo of my problem.

错误信息包括“模板参数推导/替换失败”“'city'不是从'const _gnu_cxx::__normal_iterator<_iteratorl _container>'派生的” 消息,并且我无法在网上找到与我的上述错误问题相关的任何内容。

编辑:我已经修改了我的代码,现在有了:

int main(int argc, char** argv) {

vector<city> cityList;
cityList.push_back(city(1));
cityList.push_back(city(2));
cityList.push_back(city(3));

city cityToRemove = cityList[0];
int idOfCityToRemove = cityList[0].getID();
int i;

for (i = 0; i < cityList.size(); i++) {
    cityList.erase(remove_if(cityList.begin(), cityList.end(),  cityList[i] == cityToRemove), cityList.end());
}
//remove(cityList.begin(), cityList.end(), cityToRemove);
//remove(cityList.begin(), cityList.end(), idOfCityToRemove);

return 0;
}

bool operator ==(const city &a, const city &b)
{
    return (a.id == b.id);
}

我在尝试编译时收到的错误是:

In file included from /usr/include/c++/5/bits/stl_algobase.h:71:0,
             from /usr/include/c++/5/bits/char_traits.h:39,
             from /usr/include/c++/5/ios:40,
             from /usr/include/c++/5/ostream:38,
             from /usr/include/c++/5/iostream:39,
             from main.cpp:2:
/usr/include/c++/5/bits/predefined_ops.h: In instantiation of ‘bool __gnu_cxx::__ops::_Iter_pred<_Predicate>::operator()(_Iterator) [with _Iterator = __gnu_cxx::__normal_iterator<city*, std::vector<city> >; _Predicate = bool]’:
/usr/include/c++/5/bits/stl_algo.h:866:20:   required from _ForwardIterator std::__remove_if(_ForwardIterator, _ForwardIterator, _Predicate) [with _ForwardIterator = __gnu_cxx::__normal_iterator<city*, std::vector<city> >; _Predicate = __gnu_cxx::__ops::_Iter_pred<bool>]’
/usr/include/c++/5/bits/stl_algo.h:936:30:   required from ‘_FIter std::remove_if(_FIter, _FIter, _Predicate) [with _FIter = __gnu_cxx::__normal_iterator<city*, std::vector<city> >; _Predicate = bool]’
main.cpp:30:90:   required from here
/usr/include/c++/5/bits/predefined_ops.h:234:30: error: expression cannot be used as a function
{ return bool(_M_pred(*__it)); }
                          ^

这更接近,但我不确定需要什么。但是,main.cpp:30:90 行指向我的 cityList.erase() 函数的 cityList[i] == cityToRemove 部分,所以我知道问题出在我的比较表达式中。

我的演示也更新了。

【问题讨论】:

  • 在哪里?我在这个问题中没有看到任何代码。
  • 最好将代码放在帖子中,而不是链接到外部网站。
  • 现在编辑后在帖子中包含代码以及最小示例。
  • @Jthami05: "minimal, complete" 意味着它需要可以从你的问题中复制和粘贴代码,然后编译。

标签: c++ vector erase-remove-idiom


【解决方案1】:

你需要定义一个operator ==:

class city {
    public:
        city(int idin);
        int getID();

    private:
        int id;

    friend bool operator==(const city &a, const city &b);
};

.

bool operator ==(const city &a, const city &b)
{
    return a.id == b.id;
}

还可以调用erase,如example here

【讨论】:

  • 将运算符重载函数添加到我的类并在 main.cpp 中使用 for 循环调用它作为 cityList.erase(remove_if(cityList.begin(), cityList.end(), cityList[i] == cityToRemove), cityList.end()); 减少了错误的数量,但我仍然收到“需要来自 '_ForwardIterator”错误和我无法编译。
  • 发布新代码,然后呢?以及完整的错误消息。