如何在具有非常量指针键的映射中通过常量指针键查找

bed*_*rom 7 c++ stl const-correctness const-cast const-pointer

以下 C++ 代码无法编译,因为它将非常量指针传递给需要 const 指针的find()函数。

#include <map>

std::map<int*, double> mymap;

double myfind(const int * mykey)
{
    return mymap.find(mykey)->second;
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在不改变地图类型或使变量mykey非常量的情况下使查找工作?毕竟函数find()不会修改指向的对象,它只是比较指针。

bed*_*rom 0

我想我已经找到了解决方案,但它需要 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()
}
Run Code Online (Sandbox Code Playgroud)

可以在此处找到一篇有关 C++14 透明比较器的优秀文章。说实话,通过添加比较器,类型mymap略有改变,这是我最初不想做的,但这是我能找到的最佳解决方案。

如果C++14不可用,我们至少有两个祸害可以选择。第一个是复制mymap到新的std::map<const int*, double>in 中myfind,这是非常低效的。第二个是通过使用 a 来消除常量性,如果可能的话const_cast<int*>(mykey)应该避免使用a 。