2011-04-12 10 views
12

考慮以下代碼示例:爲什麼std :: set.insert()返回一個非const迭代器,但我不能修改它?

#include <set> 
#include <string> 

using namespace std; 

set<string> string_set; 

void foo(const string& a) 
{ 
    pair<set<string>::iterator, bool> insert_result = string_set.insert(a); 

    string& val = *(insert_result.first); 
    val += " - inserted"; 
} 

所以,正確性之外,如不檢查成功插入等等,這個代碼看起來像它應該允許我修改插入後的字符串,但是編譯器(VS2010 )禁止將迭代器解引用到非常量字符串(我們正在從沒有警告的揮手之下的VS2005中遷移)。

現在,我知道這應該是禁止的,因爲它可能使字符串非唯一,我很高興它的作品是這樣的,但在現實世界的情況下,它不是那麼明確的切割,作爲我想修改一個不參與等價測試或排序的非可變數據成員。

我想知道的是,編譯器如何知道我不被允許這樣做,以及如何知道而不參考文檔(它並沒有提到這一點)?

乾杯, 蓋伊

回答

23

因爲根據標準,不允許通過 a set<>::iterator進行修改。該標準具體爲 允許set<>::iteratorset<>::const_iterator爲相同類型的 。儘管它不要求它們與 類型相同,但確實需要value_typeset<>::iterator至 爲const

原因當然是,對 值的任何修改都可能會使std::set<>的不變量失效。

3

從標準:

23.3.3

一組是一種締 容器的支持唯一關鍵字 (包含每個中的至多一個鍵值 值)並提供密鑰本身的快速檢索 。類集 支持雙向迭代器。

這也是從標準:
的typedef實現定義 迭代; //請參閱23.1

set :: iterator的實際實現是一個常量迭代器,以保持需求具有唯一鍵。否則,您可以將set中的值更改爲所有相同的值。

+0

我不認爲它返回'const_iterator',我認爲它是'第一個'成員,它是const。 – 2011-04-12 08:06:59

+0

@Michael標準說它是實現定義的。查看編輯 – 2011-04-12 08:15:07

+0

@Michael:對於'set'沒有'first',你用一個'map'混淆,我認爲它存儲了一個'pair '。 – 2011-04-12 09:57:20

相關問題