我打算用我的代码中的std ::名单,我决定不使用std ::修饰符Modifiers,因为缺失(我想)整个列表将不得不遍历,为的std ::修饰符Modifiers O(N)的复杂性(即一个链接列表)。然而,当我看着的文件,我注意到无论是STL容器有O(N)复杂删除项目。
经过一番思考我想通了,为什么(我认为)。这是因为在这两种情况下,整个列表必须进行扫描,以先找到节点,然后将其删除。这是正确的吗?
然后,我到“擦除”和“erase_after”的方法,以及它们的复杂性是“线性在擦除(破坏力)元素的数量。”。这是因为,我传递一个迭代器节点(这有点像一个“指针”)。但是,我不能(或不想)在我的代码来访问节点的数据传来传此迭代器。我不知道如果列表修改这个迭代器会有效吗?思考?
我的问题是,有没有办法,我可以得到一个指向该列表中的节点。这样一来,我知道这将是有效的在我的整个程序的生命周期,各地通过。而且我可以看看它以访问我的数据。
我不知道这是否迭代器将是有效的,如果该列表被修改
是的,在一般情况下,储存迭代器,除非你密切关注你的容器进行的操作是有风险的。
问题是,这仅仅是一个指针相同。事实上,对于很多容器,迭代器被实现为指针。
因此,无论存储迭代器或指针,如果你喜欢,但无论哪种方式,保持眼睛上的迭代器失效的规则:
但是,我不能(或不想)在我的代码来访问节点的数据传来传此迭代器。
为什么不?迭代器是易于使用,并且非常轻巧。指针是不以任何方式更好。
我不知道如果列表修改这个迭代器会有效吗?
对于list
,任何迭代器将仍然有效,即使表被修改。除此之外,当然,如果你删除这是迭代器指向特定元素。但是,这是一种明显的,你不能期望有一个迭代器(或指针)的东西,不存在任何更多。
(vector
是更危险。一个小的变化,以载体可以其无效所有迭代器。)
你可以把一个指针,指向list
任何单独的元素。
list<int> iterator it = find(l.begin(), l.end(), 7); // get an iterator
int * ptr = &*it; // get a pointer to the same element.
指针类似,在许多方面的迭代器。但是,迭代器是一个小更强大。迭代器可以递增或递减,进入相邻元素在列表中。而迭代器可用于从列表中删除的元素。指针不能做任何的那些东西。
无论是迭代器和指针只要保持有效作为该特定元件不被除去。
对于列表,迭代器是有效的,即使列表中的其他项目被删除。当该项目在列表中的迭代引用被删除它变成垃圾。
所以,只要你知道你绕过迭代器没有被一些其它的代码删除,它们是安全的守住。这似乎是脆弱的,但。
即使有迭代器引用列表中的一个节点外的结构,它会从相同的脆弱性受到影响。
但是,你可以在每个节点包含std::shared_ptr
它存储数据,而不是对象本身,然后std::weak_ptr
的绕过这些对象和访问这些expired
的前检查weak_ptr
。
例如
代替
std::list<MyClass> foo;
你将会拥有
std::list<std::shared_ptr<MyClass>> foo;
看看here对weak_ptr
的信息
有没有一种方法可以让我得到一个指向节点列表
是的,在你的具体实现。
不,一个符合标准的方式。
如果你看一下std::list documentation,没有关于一个节点一个字。虽然这是很难想象实现比使用双向链表其他std::list
不同的方式,没有什么可以阻止它。
你应该几乎从来没有接触到库无证内部的任何接触。
添加,删除和移动列表内或跨多个列表元素不坏的迭代器或引用。只有当相应的元素被删除的迭代器无效。
来源:https://en.cppreference.com/w/cpp/container/list
所以,当相应的元素被删除std::list<>::iterator
仅无效。所以,是的,只要你确保相应的元素存在(你无论如何都将在你的存储方案做/绕过一个指向任何东西),你可以保存和/或周围的迭代器通过在整个生命周期的程序。
现在,一个迭代器不过是变相的指针。所以,如果你喜欢保存/通过相应的指针,而不是周围的迭代器,你总是可以第一迭代器转换为指针@Aaron McDaid建议。
int * ptr = &*it; // get a pointer to the same element.