我有一个std ::对象列表。列表已排序,必须保持这种状态。我需要找到那些满足某个标准的对象(我有一个谓词),将它们传递给一个函数,然后从列表中删除对象。
编写一个调用std::find_if()
的循环,调用对其结果的操作(如果有的话),调用list.erase()
并将结果作为begin iterator传递它并不困难到std::find_if()
的下一个电话。然而,IME发现这样的代码比编写代码更难阅读。
所以我最好使用std lib中的一些算法,而不是编写自己的循环。
一个想法是(ab)使用std::list<>::remove_if()
:在返回true
之前,调用与谓词匹配的元素的操作,以便列表将删除元素。那是符合标准的吗? (项目本身不会被更改,只会更改他们引用的数据。)
或者你能想出更好的解决方案吗? (同样,主要目标是使其易于阅读和理解。)也许是因为我刚刚遇到它,但对我而言,这对于一系列对象来说似乎不是一种不常见的使用模式。
注意:目前,我们已经坚定地陷入了C ++ 03的土地。 :-/
C ++ 11/14/17解决方案会很有趣并因此受到欢迎,但我确实需要一些适用于C ++ 03的解决方案。
答案 0 :(得分:5)
在
remove_if
删除元素之前,我可以滥用谓词来对元素执行操作吗?
是。标准规范中没有任何内容要求谓词是纯函数。所以这个C ++ 11解决方案非常好:
my_list.remove_if([f, pred](Elem const& e){
if (pred(e)) {
f(e);
return true;
}
return false;
});
甚至不需要谓词返回true
。您甚至可以将remove_if
用作穷人,不必要地混淆for_each
:
my_list.remove_if([f](Elem const& e){
f(e);
return false;
});
这是毫无意义和低效的,但它绝对符合标准。
您可以在C ++ 03中编写等效函数作为函数对象。你是否觉得比for循环更容易阅读是一个意见问题。但这没错。