如何在迭代boost :: Intrusive :: list时擦除
How to erase while iterating boost::intrusive::list
在迭代过程中如何从 boost::intrusive::list
中删除元素?主张失败https://wandbox.org/permlink/nzfshfssairvbita
#include <iostream>
#include <vector>
#include <boost/intrusive/list.hpp>
using std::cout;
using std::endl;
class Integer : public boost::intrusive::list_base_hook<> {
public:
explicit Integer(int a_in) : a{a_in} {}
int a;
};
int main() {
auto vec = std::vector<Integer>{};
vec.push_back(Integer{1});
vec.push_back(Integer{2});
vec.push_back(Integer{3});
auto list = boost::intrusive::list<Integer>{};
for (auto ele : vec) {
list.push_back(ele);
}
for (auto it = list.begin(); it != list.end();) {
if (it->a == 2) {
it = list.erase(it);
} else {
++it;
}
}
for (auto ele : list) {
cout << ele.a << endl;
}
}
您的问题是您已将临时工推入列表:
for (auto ele : vec) {
list.push_back(ele);
}
您可能打算写:
for (auto& ele : vec) {
list.push_back(ele);
}
这是 classic 开始使用侵入容器时的混乱:没有像所有标准库容器那样按价值划分的价值。
要避免这样的情况,请考虑使用自动链接挂钩模式。
demo
甚至比不必考虑参考循环变量更安全,根本没有循环:
boost::intrusive::list<X> list(vec.begin(), vec.end());
活在coliru
#include <iostream>
#include <iterator>
#include <vector>
#include <boost/intrusive/list.hpp>
struct X : public boost::intrusive::list_base_hook<> {
X(int a_in) : a{a_in} {}
int a;
friend std::ostream& operator<<(std::ostream& os, X const& x) { return os << "{" << x.a << "}"; }
};
int main() {
std::ostream_iterator<X> out(std::cout << std::unitbuf, " ");
std::vector<X> vec { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
boost::intrusive::list<X> list(vec.begin(), vec.end());
std::cout << "before: "; std::copy(list.begin(), list.end(), out);
list.remove_if([](X const& x) { return 0 == (x.a % 2); });
std::cout << "nafter: "; std::copy(list.begin(), list.end(), out);
}
打印
before: {1} {2} {3} {4} {5} {6} {7} {8} {9} {10}
after: {1} {3} {5} {7} {9}
使用auto_unlink
:
struct X : public bi::list_base_hook<bi::link_mode<bi::auto_unlink> > {
注意,您需要禁用
list<>
的恒定时间size()
(请参阅参考)
将其安装到位,甚至添加
vec.erase(vec.begin()+4);
将正确地将相应节点与侵入列表联系起来:
活在coliru
#include <iostream>
#include <iterator>
#include <vector>
#include <boost/intrusive/list.hpp>
namespace bi = boost::intrusive;
struct X : public bi::list_base_hook<bi::link_mode<bi::auto_unlink> > {
X(int a_in) : a{a_in} {}
int a;
friend std::ostream& operator<<(std::ostream& os, X const& x) { return os << "{" << x.a << "}"; }
};
int main() {
std::ostream_iterator<X> out(std::cout << std::unitbuf, " ");
std::vector<X> vec { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
bi::list<X, bi::constant_time_size<false> > list(vec.begin(), vec.end());
std::cout << "before: "; std::copy(list.begin(), list.end(), out);
list.remove_if([](X const& x) { return 0 == (x.a % 2); });
std::cout << "nafter: "; std::copy(list.begin(), list.end(), out);
vec.erase(vec.begin()+4);
std::cout << "nauto-unlinked: "; std::copy(list.begin(), list.end(), out);
}
打印
before: {1} {2} {3} {4} {5} {6} {7} {8} {9} {10}
after: {1} {3} {5} {7} {9}
auto-unlinked: {1} {3} {6} {8} {10}
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 如何在 C 中正确使用 libiconv 使其不会报告"Arg list too long"?
- C++中带有List类的迭代器Segfault
- 使用"std::unordereded_map"映射到"std::list"对象
- GCC对可能有效的代码抛出init list生存期警告
- 使用std::list创建循环链表
- 重载Singly Linked List中的赋值运算符
- '[](std::list& list)<int>{return std::move(list)}(list)' 是否保证将 'list' 留空?
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?
- 为什么这个 std::queue/指向结构的指针列表直到 List.Size() == 0 才释放内存?
- "std::list::splice(std::const_iterator pos, std::list&& other)"是否保证将"其他"留空?
- 从嵌套循环中的 std::list 中删除将返回访问冲突
- QStringList vs list<shared_ptr<QString>> 性能比较C++
- 包含 std::list 的结构体的 C++ 初始化
- 在C++中使用 Catch 测试框架编译错误"error: expected ';' at end of declaration list"
- C++ assigment std::list:<typename>:itrator 在 main 中工作,但在方法中它不起作用
- 在基于范围的 for 循环期间插入 std::list 的后面
- 如何在迭代boost :: Intrusive :: list时擦除
- 获取迭代器在基类型 "intrusive doubly linked list" 的指针字典中的位置