std::vector::erase/remove_if resulting in nullptr
std::vector::erase/remove_if resulting in nullptr
我有一个std::shared_ptr<MotionTask>
对象的向量,我需要偶尔清理一下。
// this assert passes
assert(std::all_of(d_tasks.begin(), d_tasks.end(),
[](shared_ptr<MotionTask> task) { return bool(task); }));
// Remove any committed tasks for which the corresponding module has completed
d_tasks.erase(
remove_if(
d_tasks.begin(),
d_tasks.end(),
[module](shared_ptr<MotionTask> const& task)
{
return task->isCommitted() && task->getModule() == module;
}
)
);
// this assert fails
assert(std::all_of(d_tasks.begin(), d_tasks.end(),
[](shared_ptr<MotionTask> task) { return bool(task); }));
最终的assert
失败,因为在任务向量中有一个为null (false)。
我不明白为什么调用erase
会使成员无效。我还没能在单元测试中重现这个
是否有可以从上面的代码中观察到的解释,如果没有,我可以尝试调试它吗?
您正在调用单个迭代器std::vector::erase
过载。您需要两个迭代器版本:
d_tasks.erase(
remove_if(
d_tasks.begin(),
d_tasks.end(),
[module](shared_ptr<MotionTask> const& task)
{
return task->isCommitted() && task->getModule() == module;
}
),
d_tasks.end() // HERE!!
);
单迭代器版本删除单个元素,而erase-remove习语则需要删除一个范围。这是使用两个迭代器版本实现的。
您的问题是您使用的是vector<T>::erase
的单个迭代器版本,它擦除了一个元素。
有两种方法可以解决这个问题。第一种是使用vector<T>::erase
的双迭代器版本。二是不再使用基于迭代器的算法,而是开始编写基于容器的算法。
template<typename Container, typename Lambda>
Container&& remove_if_erase( Container&& container, Lambda&& closure ) {
using std::begin; using std::end;
container.erase(
std::remove_if(
begin(container), end(container), std::forward<Lambda>(closure)
),
end(container)
);
return std::forward<Container>(container);
}
执行一次删除元素和擦除元素的两个操作。可以编写trait类,使其不仅可以与vector
一起工作,还可以与set
和map
等关联容器一起工作。
我发现一个类似的有用的是sort_unique_erase
,它接受一个集合并删除重复项。
通过编写这种基于容器的算法,您的代码既变得更清晰,也更不容易出错,因为您不会在所有地方重复自己。许多基于迭代器的技术都以意想不到的方式悄无声息地失败了,因为一个简单的拼写错误:经过测试的基于容器的算法可以在传入的任何容器上可靠地工作,或者无法编译。
相关文章:
- 我的简单if-else语句是如何无法访问的代码
- 如何将enable-if与模板参数和参数包一起使用
- 无论条件是否为true,if总是在c++中执行
- Arduino:for/while/if在void setup()或void loop()之前?——错误:之前需要不合格
- Insert函数不适用于2 if语句C++
- If语句未被求值C++
- C++嵌套if语句,基本货币交换
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 是否可以使用if constexpr删除控制流语句
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 如何删除peer if else分支中的冗长句子
- 我似乎对if/else的基本语句有问题:/
- if数组上的随机数
- 将按位if条件转换为普通if条件
- If语句在c++中被忽略
- 比较if语句中的数组值和int值
- 使用if-else将数字转换为单词
- 为什么简单的算术减法在"if"条件下不起作用?
- 以在Qt中的IF语句中设置时间延迟
- Craps游戏问题,忽略if语句