st_ :: map的const_cast问题

时间:2011-04-19 22:04:34

标签: c++ map const

我最近遇到了一个问题,我唯一可以看到避免它的方法是使用const_cast - 但我猜测有一种方法我没有想到要避免这种情况,否则不会改变代码的功能。下面的代码片段将我的问题提炼成一个非常简单的例子。

struct Nu
{
    Nu() {v = rand();}
    int v;
};

struct G
{
    ~G()
    {
        for(auto it = _m.begin(); it != _m.end(); it++) delete it->first;
    }
    void AddNewNu()
    {
        _m[new Nu] = 0.5f;
    }
    void ModifyAllNu()
    {
        for(auto it = _m.begin(); it != _m.end(); it++) it->first->v++;
    }
    float F(const Nu *n) const
    {
        auto it = _m.find(n);
        // maybe do other stuff with it
        return it->second;
    }

    map<Nu*, float> _m;
};

这里假设Nu实际上是一个非常大的结构,其布局已经通过匹配外部库的需要而得到修复(因此“浮动”不能简单地折叠成Nu,并且出于各种其他原因,它可以' t是map<Nu, float>)。 G struct有一个映射,用于保存它创建的所有Nu(并最终在销毁时删除它们)。如上所述,函数F不会编译 - 它不能像std :: map那样强制转换(const Nu * n)到(Nu n)。但是,地图无法切换到map<const Nu*, float>,因为某些非const函数仍需要修改_m内部的Nu。当然,我可以选择将所有这些Nu 存储在一个额外的std :: vector中,然后将地图类型切换为const - 但是这会引入一个完全没必要的向量。所以我目前唯一想到的选择就是在F函数中使用const_cast(应该是一个安全的const_cast),我想知道这是否可以避免。

经过多次搜索后,这里已经解决了同样的问题:Calling map::find with a const argument

2 个答案:

答案 0 :(得分:0)

这是因为map期望Nu* const,但您已经给它const Nu*。我也发现它非常不合逻辑,不明白为什么,但事实就是这样。

答案 1 :(得分:-1)

在你的情况下,

“find”将返回一个const_iterator。把:

map<Nu*,float>::const_iterator it = _m.find(n);

...

return it->second;

我认为应该工作。

由于你是一个const方法,你当然只能阅读你的地图,而不是写/修改它