2014-01-12 25 views
2

我有一個關於std :: map迭代器行爲的問題。如果我理解正確,std :: map :: const_iterator不允許更改容器中的任何內容,但std :: map :: iterator允許同時更改它的第二個值關鍵集合(即迭代時添加/刪除元素等)。在我的情況下,我需要允許更改值,但不是密鑰集。即我需要像這樣:迭代器爲std :: map,允許修改值,但不能插入/刪除

std::map<int,int>::iterator it=m.begin() 
while(it!=m.end()) 
{ 
    ++it->second; // OK: modifying of values is allowed 
    if(it->second==1000) 
     m.erase(it++); // Error: modifying the container itself is not allowed 
    else 
     ++it; 
} 

看起來像標準迭代器不區分改變值和更改容器結構。有沒有辦法通過實現一個自定義迭代器來施加這個限制?

+1

我覺得'erase'僅僅依賴於map實例的常量而不是迭代器。 – user1781290

+0

你有沒有試過讓容器保持不變?但是,你會如何爲它添加值呢? – Gasim

+0

問題是我無法從常量容器中獲取非常量迭代器。至於你的問題,給地圖增加值可以在一個函數中完成,並在另一個函數中迭代。這不是問題,這在許多用例中通常會發生。 – bkxp

回答

2

要修改結構(即插入或刪除元素),您需要訪問底層容器的實例,而不僅僅是迭代器。

因此,通過將有問題的代碼僅訪問迭代器,而不是底層容器,可以實現要求的內容。

template <class Iter> 
cant_remove_if(Iter it, Iter end) { 
    while (it != end) { 
     ++it->second; // no problem 
     if (it->second==1000) 
      // no way to even express the concept `m.erase(it++)` here 
     else 
      ++begin; 
    } 
} 
+0

這是一個有趣的解決方案,謝謝!將代碼轉換爲迭代器對的語義並不困難,這樣做的好處顯而易見。 – bkxp

+2

或者,如果由於某種原因它需要一個位置*和*查找(但不修改)其他值,則可能會給代碼提供一個迭代器和一個對集合的「const」引用。你不能給(除了通過傳遞某種包裝到地圖)是能夠查找和修改值,但不能通過插入/擦除來修改結構。 –

相關問題