2012-07-26 37 views
1

鑑於該代碼在Visual Studio 2010:無法提領地圖常量的mapped_type迭代

void Foo::Bar() const 
{ 
    map_t::const_iterator iter(my_map_.find(key)); 

    if(my_map_.end() != iter) 
     DoStuff(iter->second); 
} 

做的東西會值乘mapped_type。映射類型是可複製的,可移動的,可分配的類型。

我收到錯誤消息,指出在嘗試訪問第二個時無法複製鍵/值對。即使我寫自己的臺詞:

iter->second; 
(*iter).second; 

,以確保它沒有任何關係DoStuff ...

我相信迭代器使得鍵/值對的一個副本返回之前,操作符 - >或運營商*。

如何獲取映射類型的副本?

編輯:

地圖本身是無符號的短褲的提高的變體,大致爲這樣:

typedef struct{} empty_t; 
typedef boost::variant<empty_t, double, long, some POD types> variant_t; 
typedef std::map<unsigned short, variant_t> map_t; 

然後作爲類的私有成員:

map_t my_map_; 

而要清楚,問題不在傳遞給DoStuff。我可以刪除該行,並簡單地取消引用迭代器,然後訪問第二個,這將導致編譯器錯誤。

if(my_map_.end() != iter) 
     iter->second; //Doesn't do anything, but illustrates the error. 
+4

你可以發表代碼exibits *只*這個問題? – 2012-07-26 20:49:25

+0

如果'T = std :: map ',那麼'T :: value_type'是'std :: pair '。注意常數。 – 2012-07-26 21:16:36

+0

正確,但我不想K,我想要V. – 2012-07-26 21:23:36

回答

0

我想通了。

WAYYYYY遠離這段代碼,並且深入一些抽象概念,映射的迭代器被傳遞給std :: partition!看起來,你不能劃分地圖。

我將地圖的內容複製到本地向量中並繼續處理,並清除了所有錯誤消息。

我不知道爲什麼編譯器變得如此困惑。問題代碼完全不相關。但沒關係。

0

編輯 答案無效;特定問題的更新如boost ::變種的結果(將與最終的答案更新一次的問題,其餘信息可用)。

如果DoStuff通過引用或通過值來引用變量,並且您直接從const_iterator傳遞變量,則DoStuff必須具有const引用或const值重載函數調用(除非對象類型具有默認的常量,常量轉換可用)。否則,編譯器會抱怨,因爲你將一個const元素視爲非const。

另一種選擇是將iter-> second分配給另一個變量(通過構造函數或賦值取決於元素類型)並將其傳遞給DoStuff - 但最好定義一個const超載版本的函數。

+0

我在原始文章中提到過,但也許我不清楚。我可以完全刪除DoStuff行。如果主體只包含迭代器聲明和「iter-> second;」,那麼該行會給出錯誤消息。所以,分配給本地的mapped_type在這一點上是無關緊要的。我將編輯原始帖子以添加說明。 DoStuff是通過值,順便說一句。 – 2012-07-26 21:06:38

+0

好吧,所以你沒有提到你之前使用boost :: variant - 如果你使用varient的單個實例的地圖,你有同樣的錯誤嗎?嘗試使用「typedef long variant_t;」並查看錯誤是否持續。如果它消失了,我認爲你的問題是迭代器不能取消引用變體類型,你可能需要通過StaticVisitor類來處理迭代器引用來處理各種情況(http://www.boost.org/)。 doc/libs/1_35_0/doc/html/variant/reference.html#variant.concepts.static-visitor) – Pyrce 2012-07-26 21:48:16