2013-05-22 52 views
2

我們(全部)知道,通過迭代器刪除元素,指針無效迭代器,例如:用std :: map :: begin調用std :: map :: erase是否安全?

std::map<..> map_; 
std::map<..>::iterator iter; 
// .. 
map_.erase(iter); // this will invalidate `iter`. 

但是,這個:

map_.erase(map_.begin()); 

是這樣安全嗎? map_.begin()將是一個有效的迭代器,指向映射的(新)第一個元素?

「測試它」不是一個解決方案。

回答

3

begin()不是一個迭代器,但返回一個迭代器。擦除第一個元素後,begin()返回另一個(有效)迭代器。

std::map<int, int> m; 
m[1] = 2; 
m[2] = 3; 
m.erase(m.begin()); // <- begin() points to 1:2 
std::cout << m.begin()->second; // <- begin() points to 2:3 now 
+0

啊哈,看起來像這樣是我(不知何故)失蹤:「begin()不是一個迭代器,但返回一個迭代器」。 –

3

cppreference,我們看到:

所有迭代器(POS,首先,最後一個)必須是有效的,並提領, 就是結束()迭代器(這是有效的,但不 無法使用)。

這幾乎可以回答你的問題。只要迭代器返回begin()是有效的無法指定,它可以用於std::map::erase()。然後一個好方法,以檢查是否begin()是OK的std::map::erase使用是通過檢查,如果它不等於end()

if(map.begin() != map.end()) { 
    map.erase(map.begin()); 
} 

或者,你也可以檢查,如果該映射爲空,如果使用std::map::erase它不是

if(!map.empty()) { 
    map.erase(map.begin()); 
} 
+1

+1指向,該地圖不能爲空 –

1

是這樣安全嗎?

是的。它將由此調用返回的臨時迭代器無效化爲begin(),並且該迭代器在語句結束時被銷燬。

map_.begin()是一個有效的迭代器,指向地圖的(新)第一個元素?

是的,除非地圖現在是空的。擦除元素並不妨礙您爲其餘元素創建新的迭代器;這會使地圖無法使用。