被 const 逼入绝境:std::map::find() const 重载

Posted

技术标签:

【中文标题】被 const 逼入绝境:std::map::find() const 重载【英文标题】:Cornered by const: std::map::find() const overload 【发布时间】:2011-04-30 23:06:13 【问题描述】:

考虑以下 sn-p:

#include <map>

class C 
public:
    C() 

    const int& f(const int& x) const
    
        // Error: cannot cast const int* to int* const
        return myMap.find(&x)->second;

        // With a const_cast works:
        //return myMap.find(const_cast<int* const>(&x))->second;
    

    std::map<int*, int> myMap;
;

int _tmain(int argc, _TCHAR* argv[])

    int x = 0;

    C c;
    c.f(x);

    return 0;

f() 中的错误是由于 map 的 find() 采用 const KeyType&amp; 的 const 重载引起的。因为映射的键类型是int*,所以这就变成了int* constf() 带一个const int&amp; 参数,这是正确的,因为该参数永远不会被修改。

不幸的是,这最终导致尝试将 const int* 强制转换为 int* const,这会丢失 int 上的 const 限定符并且无法编译。

这有点烦人,因为该参数绝对没有被修改过 - 它只是用于 find() - 但我仍然需要 const_cast 它。

有没有办法在没有const_cast 的情况下编写f()

【问题讨论】:

这很不寻常:你为什么使用指针作为映射键? 在我的应用程序中,键需要是对重量级对象的引用,并且不能将引用用作映射键。 【参考方案1】:

您只需将map 的类型更改为std::map&lt;const int*, int&gt;;不过,我质疑您是否首先需要指针作为键。正如 James 指出的那样,键类型应该是 const int*,因为您从不打算通过 map 修改所指对象。如果你这样做了,我会更加担心。

【讨论】:

【参考方案2】:

真正的问题是:为什么地图的索引不是指针 常量? (当然,假设它应该是一个指针。) 你真的希望能够通过某些东西来修改索引吗 喜欢*myMap.find(&amp;x)-&gt;first = xxx;我会说那是 很不寻常,因为你已经有一个指向 对象。

【讨论】:

以上是关于被 const 逼入绝境:std::map::find() const 重载的主要内容,如果未能解决你的问题,请参考以下文章

2019年的蔚来,2021年的苏宁?绝境还是绝境反转

《失恋33天》从绝境中走出来的故事

成熟在逆境,顿悟在绝境

绝境Uzi

人为什么要走到绝境了才能大彻大悟?

园子的商业化努力-开篇:绝境求商