2016-12-29 110 views
7

考慮下面的程序:std :: move()使迭代器失效嗎?

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,或做move構造函數/賦值無效所有迭代器?

+1

'的std :: move'確實對自己什麼都沒有。雖然這個移動任務無疑會使迭代器無效。 – user2357112

+0

也許這個質量保證會幫助:http://stackoverflow.com/questions/3413470/what-is-stdmove-and-when-should-it-be-used?rq=1 –

+0

@ user2357112 [其實...]( http://eel.is/c++draft/container.requirements.general#12)(相關的段落在n3337中相同,僅在[container.requirements.general]/11而不是12)。 – jaggedSpire

回答

0

不,他們不應該在移動操作後失效。

23.3.6.5/1

所有迭代器和插入點之前的引用不受影響,除非新的容器尺寸是比以前的容量大(在這種情況下,所有迭代器和引用被無效)

4

http://en.cppreference.com後音符(重點煤礦):

容器移動分配(過載(2)),除非ELEM後entwise 移動分配是由不兼容的分配器,引用, 指針和迭代(比結束迭代器等),以其他強制保持 有效,但指的是現在在*這元素。目前 標準使得通過毛毯聲明中保證在 §23.2.1[container.requirements.general]/12,更直接的 保證通過LWG 2321

Notes是考慮

正如hvd已經正確地指出,至少有一次情況是移動assignent被迫使迭代器無效 - 當新的容器具有不兼容的分配器時。

由於本福格特注意到有這個話題over here在更廣泛的討論,它實際上已經覆蓋了C++的問題11個方面...

+4

這是正確的但是對於一般問題,還要注意「除非元素移動分配是由不兼容的分配器強制的」:在某些情況下迭代器通過移動賦值而失效。 – hvd

+1

你可以添加這個答案http://stackoverflow.com/questions/11021764/does-moving-a-vector-invalidate-iterators?rq=1請 –