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

时间:2016-12-29 17:50:01

标签: c++ c++11 iterator undefined-behavior move-semantics

考虑以下计划:

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;
}

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

2 个答案:

答案 0 :(得分:7)

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

  

在容器移动赋值(overload(2))之后,除非是元素   移动分配是由不兼容的分配器,引用,   其他的指针和迭代器(除了结束迭代器)仍然存在   有效,但请参考现在在*中的元素。目前   标准通过一揽子声明提供此保证   §23.2.1[container.requirements.general] / 12,更直接   通过LWG 2321

正在考虑保证

备注

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

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

答案 1 :(得分:0)

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

23.3.6.5/1

  

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