C++ 在C++;,从列表中删除对象
我在写一个程序,大致是这样的:C++ 在C++;,从列表中删除对象,c++,stl,remove-if,C++,Stl,Remove If,我在写一个程序,大致是这样的: #include <list> list<MyClass> things; class MyClass { // some stuff void remove() { things.remove_if(THING_IS_ME); } }; #包括 列出事情; 类MyClass{ //一些东西 作废删除(){ 事物。如果(事物是我的话)移除; } }; 我需要写什么来代替我 换句话说,我使用一个全局S
#include <list>
list<MyClass> things;
class MyClass {
// some stuff
void remove() {
things.remove_if(THING_IS_ME);
}
};
#包括
列出事情;
类MyClass{
//一些东西
作废删除(){
事物。如果(事物是我的话)移除;
}
};
我需要写什么来代替我
换句话说,我使用一个全局STL列表作为一个集合。在某种程度上,列表中的对象会识别出它是冗余的,并希望a)将自身从列表中删除,b)将自身销毁
我该怎么做
<>我已经写了15年的C++了,我对这里的页面有点困惑:
这些谓词是什么?C++现在是否具有高阶函数?第一,简单手写循环:
for( list<MyClass>::iterator it = things.begin(); it != things.end(); /* */ ) {
if( qualifiesForDelete( *it ) ) {
it = things.erase( it );
}
else {
++it;
}
}
其中,
deletionPredicate
是一个函数或函数对象,它接受一个类型为的参数并返回bool
。返回true
的元素被视为已删除 首先,一个简单的手写循环:
for( list<MyClass>::iterator it = things.begin(); it != things.end(); /* */ ) {
if( qualifiesForDelete( *it ) ) {
it = things.erase( it );
}
else {
++it;
}
}
其中,deletionPredicate
是一个函数或函数对象,它接受一个类型为的参数并返回bool
。返回true
的元素被视为已删除 (最初是一组注释,但在发现OP真正想要做的事情后重写为答案。)
您知道STL容器存储您插入的内容的副本,对吗?这意味着
MyClass
的实例最好具有可比性(例如,通过operator==
)-您不能只比较地址,因为它们总是不同的
如果拥有MyClass的副本没有任何意义,那么你最好还是使用它
,C++语言默认使用复制语义。该语言要求您在代码中明确引用之类的内容。我强烈建议您重新开始,否则您将在将来被类似的问题绊倒。
(最初是一组注释,但在发现OP真正想要做的事情后重写为答案。)您知道STL容器存储您插入的内容的副本,对吗?这意味着
MyClass
的实例最好具有可比性(例如,通过operator==
)-您不能只比较地址,因为它们总是不同的
如果拥有MyClass的副本没有任何意义,那么你最好还是使用它
,C++语言默认使用复制语义。该语言要求您在代码中明确引用之类的内容。我强烈建议您重新开始,否则将来会被类似的问题绊倒。
如果函数包含三个参数,则remove\u:两个迭代器定义您正在处理的范围,以及一个谓词(返回bool
的测试函数)。开始迭代器指向要处理的第一个元素;结束迭代器指向范围中最后一个元素之后的元素
在来自的示例中,谓词是表示
bool IsOdd (int i) { return ((i%2)==1); }
要使代码实现您想要的功能,您需要编写如下内容:
things.remove_if(things.begin(), things.end(), SomePredicateFunction);
您可以这样定义SomePredicateFunction
(用适当的测试替换true
):
remove\u if
函数有三个参数:两个迭代器定义正在处理的范围,以及一个谓词(返回bool
的测试函数)。开始迭代器指向要处理的第一个元素;结束迭代器指向范围中最后一个元素之后的元素
在来自的示例中,谓词是表示
bool IsOdd (int i) { return ((i%2)==1); }
要使代码实现您想要的功能,您需要编写如下内容:
things.remove_if(things.begin(), things.end(), SomePredicateFunction);
您可以这样定义SomePredicateFunction
(用适当的测试替换true
):
在过去的15年里,C++的情况发生了巨大的变化。1994年7月,亚历山大·斯捷潘诺夫(Alexander Stepanov)提出的一个包含他关于泛型编程思想的库的建议得到了ANSI/ISO委员会的最终批准。我们今天方便地调用的这个库后来成为标准的C++库。STL的故事和它背后的思想一样引人入胜,绝对值得一读
您发现的std::remove_if()
函数只是这种哲学的另一个反映,它已成为C++现代身份的一部分。简言之,这是一个通用函数,它将在元素的任何容器(序列)和任何(行为类似于)条件下工作。为此,您必须提供两个功能:
两个迭代器,用于限定要处理的元素范围李>
以及一个谓词,当对元素调用时,如果要删除该元素,则返回true,否则返回false
事实证明,在本例中,您需要的谓词是相等谓词。由于基于相等性删除元素是一项非常常见的任务,因此该标准还提供了std::remove()
函数,该函数采用隐式相等谓词。当然,您必须确保元素可以比较:
bool operator==(const MyClass& a, const MyClass& b)
{
// return true if the two are equal, and false otherwise.
}
然后,我们可以使用谓词删除MyClass
类型的元素:
std::remove(things.begin(), things.end(), *this); // if *this == elem
回想一下,标准函数std::remove()
适用于任何容器,即使是尚未创建的容器。因为每种容器都有自己的删除元素的方法,所以如果不知道它所使用的容器的实现细节,这个函数就不能真正执行删除。因此,std::remove()
函数交换周围的元素,使元素“removed”位于容器的末尾。然后,它返回一个迭代器,该迭代器指向“删除”的连续元素中的第一个元素
在一行中看到此类代码并不少见:
things.erase(std::remove(things.begin(), things.end(), *this),
things.end());
这一切都可能是错误的
things.erase(std::remove(things.begin(), things.end(), *this),
things.end());