C++ 从类中删除列表元素

C++ 从类中删除列表元素,c++,list,erase,C++,List,Erase,我试图删除列表元素,但总是收到错误消息 首先我有这个班级结构: Class X { public: ID; name; } 然后我有一个列表容器 void delete ( list<X> a , X b ) { list<X>::iterator itr; for ( itr =a.begin() ; itr != a.end() ; itr++ ) { if ( *itr.ID == b.ID ) { a.erase(itr) ; } }

我试图删除列表元素,但总是收到错误消息

首先我有这个班级结构:

Class X
{ public:
  ID;
  name;
}
然后我有一个列表容器

void delete ( list<X> a , X b )
{

list<X>::iterator itr;

for ( itr =a.begin() ; itr != a.end() ; itr++ )
{
    if ( *itr.ID == b.ID )
    { a.erase(itr) ; }
}
}
现在,我想从容器中删除特定的元素

void delete ( list<X> a , X b )
{

list<X>::iterator itr;

for ( itr =a.begin() ; itr != a.end() ; itr++ )
{
    if ( *itr.ID == b.ID )
    { a.erase(itr) ; }
}
}
void删除(列表a,X b)
{
列表::迭代器itr;
对于(itr=a.begin();itr!=a.end();itr++)
{
如果(*itr.ID==b.ID)
{a.擦除(itr);}
}
}
但是,我得到了一个错误:

“迭代器没有ID”


我怎样才能修好它

这是因为点运算符
比解引用运算符
*
强。根据,点的优先级为2,而取消引用星号
*
的优先级为3(越低越好)。这意味着,如果没有括号,编译器将尝试获取迭代器的成员
ID
,然后取消引用
ID
的值。这是不可能的,因为迭代器没有名为
ID
的成员

您需要使用括号来强制执行所需的优先级:

if ( (*itr).ID == b.ID )
或者,您可以使用
->
运算符取消对迭代器的引用:

if ( itr->ID == b.ID )
注:C++标准库提供了一种无循环的方式:

a.erase(
    remove_if(
        a.begin()
    ,   a.end()
    ,   [](X x){ return x.ID == b.ID; }
    )
,   a.end()
);

我更喜欢使用itr->ID而不是*itr.ID。后者有时有点令人困惑。

不仅仅是困惑;没有括号是错误的,正如问题所说。一旦你解决了这个问题,你就必须为函数找到一个新名称,因为
delete
是一个关键字<代码>擦除和
删除
是常见的选择。您还需要通过引用传递
a
,并记住迭代器无效规则。或者你可以让生活更轻松,使用
a.remove(b)
@MikeSeymour你的意思是通过
a
byreference@bolov:的确如此。已更正。@MikeSeymour如果([&](X const&X){return X.ID==b.ID;}),则将是
a.remove\u,不是吗?@JamesKanze:你说得对,我可能应该避免在没有先编译它们的情况下快速提出建议。/tmp/ccOJ9JuT.o:在函数
delete(std::list,X)':a.cpp:(.text+0x0):
delete(std::list,X)'多定义中,我现在得到了这个错误。但是,我从代码中删除了此函数,请正确运行。@ort23您需要重命名
delete
函数,它是一个保留名称。@ort23这很奇怪。你在头文件中定义了你的函数吗?@ort23那就是问题所在。您应该在标题中声明它(即
void erase(列表a,X b);
delete
函数的新名称),并在CPP文件中定义它。否则,每次在CPP文件中包含头时都会有重复的定义。他仍然会遇到问题:删除迭代器指向的元素会使迭代器无效,因此他的循环无法工作。