2016-08-05 47 views
1

請看下面的例子:爲什麼下面不工作時,地圖是量靜態

enum class DOG_TYPE {SHEPHARD, COLLIE,UNKNOWN}; 

static const std::map<std::string,DOG_TYPE> dogMap = { 
       {"GS",DOG_TYPE::SHEPHARD} 
}; 


DOG_TYPE getDogType(const std::string& dogtype) 
{ 
    if(dogMap.find(dogtype) != dogMap.end()) 
    { 
     return dogMap[dogtype]; -->Does not work when std::map is constant 
    } 
} 

int main() 
{ 
DOG_TYPE j = getDogType("GS"); 
std::cout << int(j); 
} 

在上面的例子中陳述return dogMap[dogtype];返回錯誤

error: passing 'const std::map<std::__cxx11::basic_string<char>, DOG_TYPE>' as 'this' argument discards qualifiers [-fpermissive] 
     return dogMap[dogtype]; 

我想知道爲什麼這發生了,爲什麼不能映射爲const static

+1

相關:[爲什麼std :: map沒有const訪問器?](http://stackoverflow.com/questions/13902742/) –

回答

7

std::map上使用operator[]創建該對象(如果它不存在)。所以這是一個只能在允許修改的地圖上執行的操作。改爲使用find

+0

是的,這是正確的。感謝您清除 –

5

它不起作用,因爲std::map沒有被聲明爲const一個operator[],所以你不能一個const std::map對象使用operator[]

std::map::operator[]被定義爲將參考返回到鍵控值。如果未找到密鑰,則將映射修改爲以爲該密鑰插入默認值,以便它可以綁定返回的引用。顯然,修改const std::map無法工作,因此編譯器錯誤。

要做你正在嘗試的事情,你可以使用std::map::find()搜索密鑰而不插入新的值。如果找到密鑰,則可以取消引用返回的iterator

如果未找到密鑰,請不要忘記讓您的函數返回默認值。

試試這個:

DOG_TYPE getDogType(const std::string &dogtype) 
{ 
    auto iter = dogMap.find(dogtype); 
    if (iter != dogMap.end()) 
     return iter->second; 
    return DOG_TYPE::UNKNOWN; 
} 
1

至於說其他,operator[]修改地圖如果該鍵不存在。

但是你可以使用at()

DOG_TYPE getDogType(const std::string& dogtype) 
{ 
    if(dogMap.find(dogtype) != dogMap.end()) 
    { 
     return dogMap.at(dogtype); 
    } 
} 

而且,如果你能負擔得起的getDogType()拋出異常時dogtypedogMap的關鍵,簡單地

DOG_TYPE getDogType(const std::string& dogtype) 
{ 
     return dogMap.at(dogtype); 
} 

PS:只有at()可用來自C++ 11

ps2:抱歉我的英文不好。

+0

因爲您將執行2次相同的搜索以獲得1個結果,所以使用'find()'和'at()'是多餘的。 *(*)使用* * find()'*或*',而不是* both *。 –

+0

@RemyLebeau - 你是對的:我的第一個例子是無效的(第二個問題,因爲當OP可能想要'UNKNOWN'而不是異常時拋出一個異常)。作爲一個藉口,我說我的意圖只對OP顯示,當'at()'存在時(來自C++ 11),const操作符[]'只存在於非const模式下。 – max66

相關問題