c++ - 即使谓词返回 false,remove_if 也会删除元素?
问题描述
我正在写一个八叉树算法。在函数内部我遍历八叉树。我得到节点指针和球体作为输入。我检查节点是否应该保持球体然后我想将它添加到节点s object list and remove it from its parent
的列表中。以下是代码
functionBody()
{
.....
if (!node->objectList.empty())
node->objectList.erase(std::remove_if(node->objectList.begin(), node->objectList.end()-1 , [&t](auto& temp) { return temp == t; }));
...
}
typedef struct Sphere
{
Sphere() = default;
Sphere(const Vector3 centre_, const float radius_, const Material& material_) : centre(centre_), radius(radius_), material(material_)
{
assert(radius != 0);
invRadius = 1.0 / radius;
Vector3 radiusOffset = Vector3(radius);
aabb.min = Vector3(centre - radiusOffset);
aabb.max = Vector3(centre + radiusOffset);
}
bool operator==(const Sphere& rhs)
{
return (centre == rhs.centre) && (radius == rhs.radius);
}
Vector3 centre;
float radius;
float invRadius;
Material material;
AABB aabb;
}Sphere;
正如你所看到的,我已经operator==
定义了 Sphere。
我看到remove_if
即使谓词返回错误,它也会删除元素。
例如,第一次迭代它找到一个球体t
并使用remove_if
. 这t
最后出现在向量中。现在考虑父母在其向量中仍然有3个球体,但是,当我现在去其他孩子时,我们仍然尝试t
在父母中搜索并且remove_if
仍然删除最后一个条目。我不明白为什么?
解决方案
std::remove_if
返回end
没有找到要删除的内容时提供的迭代器。您已经给出node->objectList.end()-1
了结束迭代器,它是 . 中最后一个元素的迭代器node->objectList
。这是您erase
在找不到时传递给t
的内容,因此最后一个元素被删除。
要解决此问题,请使用erase
需要一系列元素的重载:
if (!node->objectList.empty())
{
auto end_iter = node->objectList.end();
auto to_remove = std::remove_if(
node->objectList.begin(), end_iter,
[&t](auto& temp) { return temp == t; });
node->objectList.erase(to_remove, end_iter);
}
现在 if t
is not founderase
根本不会做任何事情。在这种情况下,remove_if
返回end_iter
并erase
尝试擦除由end_iter
和自身定义的空范围内的元素。
我不确定你为什么使用node->objectList.end() - 1
. 我假设这是一个错误或解决方法,否则您可能会在以前的代码中遇到这种情况。
推荐阅读
- javascript - 在 reactjs 组件中返回重定向推送时浏览器后退按钮不起作用(仅 Chrome 和 Edge - 在 firefox 中可以)
- c++ - 如何通过对代码进行相当小的更改来修复未定义的行为
- c# - CreateRemoteThread 运行没有错误,但没有任何反应
- typescript - 使用 jest 和 sequelize-mock 在嵌套应用程序中测试使用 sequelize-typescript 定义的 sequelize 模型
- google-bigquery - 如何离开加入自定义维度和交易
- javascript - JSPDF blob url react-native-webview
- redis - 限速理论(redis)
- python - 如何将 pkl 文件转换为 pandas 数据框
- javascript - 在图像 (PNG) 中转换 ZPL (Base64)
- python - 在 Apache Airflow 中,您可以依赖先前运行的任务吗?