如何通过与非const指针键映射一个常量指针键查找

问题描述 投票:3回答:4

以下C ++代码不编译,因为它通过一个非const指针,该期望一个const指针find()功能。

#include <map>

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

double myfind(const int * mykey)
{
    return mymap.find(mykey)->second;
}

有没有办法如何使找工作,而不改变地图的类型或制造变量mykey非const?所有find()不修改尖锐的物体功能后,它只是比较指针。

c++ stl const-correctness const-cast const-pointer
4个回答
1
投票

地图中的一个关键是语义上不可变的,所有映射操作,允许键直接访问做到这一点的const-资格密钥类型(例如value_type被定义为pair<const Key, T>)。

int*密钥类型的情况下,但是你会得到一个const指向非const intint*const),这是不是很漂亮的(它仍然有效,因为只有指针值作为重点,而是永恒的语义被稀释,这可能会导致错误)。

相反虚掷常量性的,只是改变mapmap<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
}

0
投票

尝试const_cast它允许你改变变量的常量性(或波动)。

#include <map>

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

double myfind(const int * mykey)
{
    return mymap.find(const_cast<int*>(mykey))->second;
}

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()
}

优异的文章关于C ++ 14透明比较可以发现here。要完全诚实的,通过添加比较,mymap类型略有改变,我本来不想来,但它是我能找到的最好的解决方案。

如果C ++ 14不可用,至少有两两害相权,我们可以选择。第一个是mymap复制到std::map<const int*, double>myfind,这是可怕的效率不高。第二个是通过使用应const_cast<int*>(mykey)如果可能的话avoided铸造远常量性。


-1
投票

你可能有一个const,正确性问题。 const int * may not be what you think it is。它是一个指向一个常数整数。这是不一样的地图,这是一个指向(非恒定)整数的键类型。而且,无论是相同的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指向指针我通过,但如果你在一个int *的键使用这样的指针std::map,你可能会允许某人修改该int

在这种特殊情况下,我们知道std::map::find()不会分配给指针参数,但是编译器没有,这就是为什么const_cast<>存在在其他的答案中指出。

© www.soinside.com 2019 - 2024. All rights reserved.