std :: move()是否使迭代器无效?

Kar*_*oll 9 c++ iterator undefined-behavior move-semantics c++11

考虑以下程序:

struct list_wrapper
{
    std::vector<int>    m_list;
};

int main()
{
    std::vector<int> myList { 1, 1, 2, 3, 5 };

    const std::vector<int>::iterator iter = myList.begin();

    list_wrapper wrappedList;
    wrappedList.m_list = std::move(myList);

    // Can I still dereference iter?

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在调用之后std::move(myList),iter现在指向内部的有效项wrappedList.m_list,或者移动构造函数/赋值使所有迭代器无效?

W.F*_*.F. 7

http://en.cppreference.com注意后(强调我的):

在容器移动赋值(overload(2))之后,除非元素移动赋值由不兼容的分配器强制执行,引用,指针和迭代器(除了结束迭代器)仍然有效,但引用现在在*this中的元素.当前标准通过§23.2.1[container.requirements.general]/12中的一揽子声明进行此保证,并且正在通过LWG 2321考虑更直接的保证.

笔记

正如hvd正确地指出的那样,至少有一种情况是移动分配器被迫使迭代器失效 - 当新容器具有不兼容的分配器时.

正如Ben Voigt所指出的那样,这个主题在这里有更广泛的讨论,它实际上已经涵盖了问题的c ++ 11方面......

  • 这是OP代码的正确粗体,但对于一般问题,还要注意"除非元素移动赋值由不兼容的分配器强制":有些情况下迭代器由移动赋值无效. (4认同)

Wag*_*ota 0

不,它们不应在移动操作后失效。

23.3.6.5/1

插入点之前的所有迭代器和引用不受影响,除非新容器大小大于先前的容量(在这种情况下所有迭代器和引用都无效)