簡體   English   中英

如何通過非const指針鍵在地圖中找到const指針鍵

[英]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 intint*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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM