[英]How to find by a const pointer key in a map with non-const pointer keys
以下C ++代碼無法編譯,因為它將非const指針傳遞給需要const指針的find()
函數。
#include <map>
std::map<int*, double> mymap;
double myfind(const int * mykey)
{
return mymap.find(mykey)->second;
}
有沒有辦法如何在不改變地圖類型或使變量mykey
非const的情況下使查找工作? 在所有函數find()
不修改指向對象之后,它只是比較指針。
映射中的鍵在語義上是不可變的,所有允許直接訪問鍵的映射操作都通過對鍵類型進行const
限定來實現(例如, value_type
被定義為pair<const Key, T>
)。
在int*
key類型的情況下,你會得到一個指向非const int
( int*const
)的const
指針,這不是很好(它仍然有效,因為只有指針值用作鍵,但是不變性的語義被稀釋,這可能導致錯誤)。
而不是丟棄constness,只需將map
更改為map<const int*, double>
。
然后它將適用於const int*
以及int*
鍵。
#include <map>
std::map<const int*, double> mymap;
double myfind(const int * mykey)
{
return mymap.find(mykey)->second; // just works
}
double myfind(int * mykey)
{
return mymap.find(mykey)->second; // also works
}
嘗試使用const_cast
,它允許你改變變量的常量(或波動性)。
#include <map>
std::map<int*, double> mymap;
double myfind(const int * mykey)
{
return mymap.find(const_cast<int*>(mykey))->second;
}
我想我找到了一個解決方案,但它需要C ++ 14透明比較器。
#include <map>
#include <iostream>
struct CompareIntPtrs
{
using is_transparent = void; // enabling C++14 transparent comparators
bool operator()(const int * l, const int * r) const
{
return l < r;
}
};
std::map<int*, double, CompareIntPtrs> mymap;
double myfind(const int * key)
{
return mymap.find(key)->second;
}
int main()
{
int x {6};
mymap[&x] = 66; // inserting to the map
const int * px = &x; // creating a "const int *" variable
std::cout << myfind(px) << std::endl; // using "const int *" for finding in map with "int*" keys
std::cout << mymap.find(px)->second << std::endl; // we could even skip using myfind()
}
約C ++ 14個透明比較優異的制品可以找到這里 。 說實話,通過添加比較器, mymap
的類型略有改變,這是我原本不想要的,但它是我能找到的最佳解決方案。
如果C ++ 14不可用,我們可以選擇至少兩個邪惡。 第一種是拷貝mymap
到一個新std::map<const int*, double>
在myfind
,這是可怕的效率不高。 第二個是通過使用const_cast<int*>(mykey)
來const_cast<int*>(mykey)
,如果可能的話應該避免使用它。
您可能有一個const正確性問題。 const int *
可能不是你想象的那樣 。 它是一個指向常量整數的指針 。 這與地圖的鍵類型不同,后者是指向(非常數)整數的指針 。 並且它們都不是int * const
,它是一個指向(非常量)整數的常量指針 。 問題不在於鍵值本身是可變的還是不可變的,而是存儲指針的東西是可變的還是不可變的。
例如,這編譯:
std::map<int *, double> mymap;
double myfind(int * const mykey) {
return mymap.find(mykey)->second;
}
就像這樣:
std::map<const int *, double> mymap;
double myfind(const int *mykey) {
return mymap.find(mykey)->second;
}
double myfind2(const int * const mykey) {
return mymap.find(mykey)->second;
}
你看得到差別嗎? 在原始代碼中,編譯器標記錯誤是完全正確的。 如果你的函數采用const int *
,那么你實際上承諾不會修改我傳入的指針所指向的int
。但是如果你在std::map
的鍵中使用這樣的指針作為int *
,那么你可能允許某人修改該int
。
在這種特殊情況下,我們知道std::map::find()
不會分配給指針參數,但編譯器不會,這就是const_cast<>
存在的原因,如其他答案中所指出的那樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.