我们都知道vector<T>
中的元素地址可能会在我们追加更多元素时(由于调整大小)而改变,而list<T>
中的元素仍保留在同一地址。
问题是,vector<list<T>>
怎么办?例如,
vector<list<T>> container;
// Insert some elements to container...
T* ptr = &(container[0].back());
// Insert more elements to container...
我们可以假设ptr
保持有效吗?
天真,我认为应该这样,因为当向量调整大小时,它应该调用list<T>
的移动构造函数,它不应该复制/移动单个元素。但是,我不知道标准是否能确保这一点。
答案 0 :(得分:4)
抱歉,没有。 std::list
移动构造函数不是noexcept
。调整大小时std::vector
使用std::move_if_noexcept
,这将是包含的std::list
的副本。将分配和复制所有列表节点。他们的地址不稳定。
答案 1 :(得分:1)
您应该将其设为vector<list<T>*>
而不是vector<list<T>>
。使用vector<list<T>*>
,您可以确定包含的指针不会被更改(并且不会对内部列表进行任何重量级的复制),因为它们是向量的值和值的值。向量不会被扩展逻辑改变。这比依靠复制内部列表仅移动头元素而不重新分配任何剩余节点(这也更容易理解)要安全得多。以另一种方式做这件事很难理解,只是玩火。