我有一个对象的 std::list。该列表已排序并且必须保持该状态。我需要找到那些满足特定条件的对象(我有一个谓词),将它们传递给一个函数,然后从列表中删除这些对象。
编写调用std::find_if()
的循环并不难, 对其结果调用操作(如果有),调用 list.erase()
, 并将其结果作为开始迭代器传递给下一次调用 std::find_if()
.然而,IME,人们发现这样的代码比编写它更难阅读。
所以我更愿意使用标准库中的一些算法,而不是编写自己的循环。
一个想法是(滥用)使用 std::list<>::remove_if()
: 在返回 true
之前,对匹配 谓词 的元素调用操作, 这样列表就会删除元素。那会符合标准吗? (项目本身不会改变,只会改变它们引用的数据。)
或者您能想出更好的解决方案吗? (同样,主要目标是使它易于阅读和理解。)也许是因为我刚遇到它,但对我来说,这似乎不是一个对象序列的不常见使用模式。
注意:目前,我们牢牢地停留在 C++03 领域。 :-/
C++11/14/17 解决方案会很有趣,因此很受欢迎,但我确实需要一些适用于 C++03 的东西。
最佳答案
Can I abuse a predicate to perform operations on the elements before
remove_if
removes them?
是的。标准规范中没有任何内容要求谓词是纯函数。所以这个 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 循环更容易阅读是一个见仁见智的问题。但这并没有错。
关于c++ - 我可以滥用谓词在 remove_if 删除元素之前对元素执行操作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41527685/