2014-08-28 99 views
0

我收到以下錯誤消息:「表達式必須是可修改的左值iter-> first = iter-> second;」代碼:對的集合的迭代器是const?

func(const std::set<Edge> &obstructEdges1, 
     const std::set<Edge> &obstructEdges2) 
{ 
std::set<Edge> obstructEdges = obstructEdges1; 
obstructEdges.insert(obstructEdges2.begin(), obstructEdges2.end()); 

for (std::set<Edge>::iterator iter = obstructEdges.begin(); 
    iter != obstructEdges.end(); iter++) 
{ 
    if (iter->first > iter->second) 
    { 
    int t = iter->first; 
    iter->first = iter->second; 
    iter->second = t; 
    } 
... 

Edge是一對整數。怎麼了?由於某種原因,看起來像iter->first被認爲是const

+0

@ juanchopanza我將常量集合複製到非常量集合中。 – 2014-08-28 20:53:53

+1

相似的(在AndreyT的答案後發現):http://stackoverflow.com/questions/4064841/strange-error-setintbegin-always-returning-const-iterator – 2014-08-28 20:58:00

回答

4

是,std::set迭代器始終是一個常量迭代即使該組本身不是const,即std::set::iteratorstd::set::const_iterator都是恆定迭代器(並且可以指的是相同的類型)。請注意,std::set是一個關聯容器。在標準關聯容器中,您不允許修改已存儲的密鑰,這意味着您在std::set中不允許修改任何內容。當然,你的比較器不必將整個集合元素當作關鍵字,但從整個角度來看,整個事物是關鍵,因此是不可變的。

,因爲它說在23.2.4

迭代關聯容器的是雙向迭代類。對於值類型爲 與關鍵字類型相同的關聯容器,iterator和const_iterator都是 常量迭代器。未指定迭代器和const_iterator是否是相同的類型。

+0

哇,我沒有意識到我想改變關鍵。 .. – 2014-08-28 20:58:50

4

set<T>::iterator始終*恆定的迭代器,就像set<T>::const_iterator,所以你不能用它來修改設定的任何元素。如果你可以直接修改這個集合的元素,那麼這個集合很可能變成無序的,這隻會導致Bad Things™。

*好吧,至少從C++ 11開始,儘管至少在任何主要實現中都不可能有很長的非const集迭代器。

+0

我昨天注意到'set :: begin()'在VS2008中返回一個非const迭代器。但是,VS2008是古老的:) – 2014-08-28 21:00:02

+0

我在過去使用過非const的'set'迭代器,它非常有用。您將對象的一部分設置爲密鑰,必須保持不變,但您可以隨意修改對象的其餘部分。我很難過看到該功能消失。 – 2014-08-28 22:10:26