【发布时间】:2020-10-07 15:47:52
【问题描述】:
我有一个对象列表:
std::list<A> objects;
为了触发异步操作,根据某些条件将它们从列表中删除,对象需要知道它们在列表中的位置:
A::A(std::list<A>::iterator it);
向列表添加项目时如何将迭代器传递给构造函数?
objects.emplace(<the iterator to new item>);
后面无法初始化class A的成员迭代器,即使构造函数也可能触发删除操作,所以在构造时需要这个成员。
我想到的可能解决方案(带来额外的复杂性):
1:
objects.emplcae(A(objects.end())); // dummy object
A a{ std::prev(objects.end()) };
std::swap(a, object.back());
2:
objects.emplace();
objects.back().set_iterator(std::prev(objects.end()));
objects.back().run(); // Moved the work from constructor to this function (against RAII)
3:尝试根据this的地址获取迭代器。
【问题讨论】:
-
您是否考虑过对象不必从列表中删除的替代方案?此外,
std::list本身并不是线程安全的,因此如果对象异步运行,您可能无法安全地删除它自己。 -
是的,在我当前的实现中,对象不会自行删除,我需要不时触发列表中的删除操作,并且需要遍历所有对象。我的异步模型使用 asio io_context 并且我从单线程运行它,因此所有处理程序都将在单线程中运行。如果我从多个线程运行它,那么我需要处理线程安全。
-
为什么不能从对象的地址中获取迭代器?我认为列表项是对象后跟两个指向 prev 和 next 的指针,而迭代器是指向该对象的指针。
-
迭代器可能会也可能不会被实现为指向对象的指针。并且结束指针肯定不会指向列表中的项目。