被 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&
的 const 重载引起的。因为映射的键类型是int*
,所以这就变成了int* const
。 f()
带一个const int&
参数,这是正确的,因为该参数永远不会被修改。
不幸的是,这最终导致尝试将 const int*
强制转换为 int* const
,这会丢失 int 上的 const 限定符并且无法编译。
这有点烦人,因为该参数绝对没有被修改过 - 它只是用于 find() - 但我仍然需要 const_cast
它。
有没有办法在没有const_cast
的情况下编写f()
?
【问题讨论】:
这很不寻常:你为什么使用指针作为映射键? 在我的应用程序中,键需要是对重量级对象的引用,并且不能将引用用作映射键。 【参考方案1】:您只需将map
的类型更改为std::map<const int*, int>
;不过,我质疑您是否首先需要指针作为键。正如 James 指出的那样,键类型应该是 const int*
,因为您从不打算通过 map
修改所指对象。如果你这样做了,我会更加担心。
【讨论】:
【参考方案2】:真正的问题是:为什么地图的索引不是指针
常量? (当然,假设它应该是一个指针。)
你真的希望能够通过某些东西来修改索引吗
喜欢*myMap.find(&x)->first = xxx
;我会说那是
很不寻常,因为你已经有一个指向
对象。
【讨论】:
以上是关于被 const 逼入绝境:std::map::find() const 重载的主要内容,如果未能解决你的问题,请参考以下文章