这是一个简单的代码
#include <map>
class MyMap : public std::multimap<int*, int*>
{
public:
void foo(const int* bar) const
{
equal_range(bar);
}
};
int main()
{
MyMap myMap;
int number;
myMap.foo(&number);
return 0;
}
它不编译,并给出以下错误
error C2663: 'std::_Tree<_Traits>::equal_range' : 2 overloads have no legal conversion for 'this' pointer
我看过很多关于此错误的主题,似乎是const
问题。如果我将foo(const int* bar)
转换为foo(int* bar)
,则编译得很好。
问题是,我没有看到foo
内容应该如何改变我的MyMap对象。 std::multimap
提出了equal_range
的const版本:
http://www.cplusplus.com/reference/map/multimap/equal_range/
我的问题是什么?
谢谢
答案 0 :(得分:1)
检查equal_range的定义:
pair<const_iterator,const_iterator> equal_range (const key_type& k) const;
它希望不断引用key_type
:const key_type& k
。
您尝试提供的是指向常量整数的指针:const int* bar
为什么即使两个值均为const
?
const int& foo
的常量引用意味着您不能让foo
引用另一个整数,但允许更改引用的整数的值。const int* foo
的指针意味着您可以让foo
指向另一个整数,但不能更改它指向的整数的值。地图实际需要的是const int*& k
,但如果您仅提供int*
(不包含const
),地图会自动转换此内容。
[编辑]
另请注意,即使您将MyMap
更改为foo
,const int*
功能仍然无法更改int*
对象,因为在结尾处还有另一个const你的foo
功能。最后的const将函数声明为常量,这意味着它不能修改执行它的当前对象。如果它试图修改它或调用任何可能修改它的东西,你会得到编译器错误。 (免责声明:有一些方法可以在const函数中修改类,但这是另一个主题。)
答案 1 :(得分:0)
如果正确的编译器消息可以给你答案。对于两个重载中的一个(const
一个):
/usr/local/include/c++/v1/map:1836:41: note: candidate function not viable: 1st argument ('const int *')
would lose const qualifier
const int*
是指向const int
的指针。该方法需要const key_type&
,即const int*&
参数,这是对{non - const
} const
的{{1}}引用。
如果感到困惑,请更喜欢将int*
写为const int*
,这是同一回事。然后,您会更清楚地看到与int const*
的区别。
要使代码生效,请使用const int*&
代替int*
。
答案 2 :(得分:0)
我认为问题与key_type
上的不匹配有关。
一方面,你有一个多图,其中key_type=int*
,而另一方面,你传递key_type=const int*
,因此试图删除key_type
上的const限定符。我也对此感到困惑,因为我正在扩展我的key_type
以获得应该兼容的const int*&
。但是,不匹配发生在key_type
本身的早期。至少这是我能想到的唯一合乎逻辑的解释。
我的建议是制作key_type
const int*
并保持您的函数参数不变。毕竟,为什么你需要一个指向可变值的指针作为地图的关键?