2011-04-30 37 views
5

考慮下面的代碼片段:以const走投無路:性病::地圖::找到()const的重載

#include <map> 

class C { 
public: 
    C() {} 

    const int& f(const int& x) const 
    { 
     // Error: cannot cast const int* to int* const 
     return myMap.find(&x)->second; 

     // With a const_cast works: 
     //return myMap.find(const_cast<int* const>(&x))->second; 
    } 

    std::map<int*, int> myMap; 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int x = 0; 

    C c; 
    c.f(x); 

    return 0; 
} 

f()錯誤是由地圖的find() const的過載採取const KeyType&引起的。由於地圖的關鍵類型爲int*,因此這將變爲int* constf()需要const int&參數,這是正確的,因爲該參數從不被修改。

不幸的是,這最終試圖將const int*投射到int* const,它丟失了int上的const限定符並且不會編譯。

這是一種刺激性的,因爲絕對參數沒有修改過 - 它只是用於查找() - 但我仍然需要const_cast它。

有沒有辦法寫f()沒有const_cast

+1

這很不尋常:你爲什麼使用指針作爲映射鍵? – 2011-04-30 23:08:00

+0

在我的應用程序中,鍵需要是對重量級對象的引用,並且不能將引用用作映射鍵。 – AshleysBrain 2011-04-30 23:15:31

回答

5

真正的問題是:爲什麼不是地圖的索引指針 要const? (當然,假設它應該是一個指針。) 你真的希望能夠通過 之類的東西修改索引,比如*myMap.find(&x)->first = xxx;我會說那是 很不尋常,因爲你已經有了一個指向 對象的指針。

+0

啊,沒有想到 - 謝謝! – AshleysBrain 2011-04-30 23:42:59

7

您可以將map的類型更改爲std::map<const int*, int>;不過,我首先問你是否需要指針作爲鍵。正如詹姆斯指出的那樣,關鍵類型應該是const int*,因爲你從不打算通過map修改指代物。如果你這樣做,我會更加擔心。