C++ C++;通过指针对象键访问映射元素时出现非法操作错误

C++ C++;通过指针对象键访问映射元素时出现非法操作错误,c++,dictionary,constants,C++,Dictionary,Constants,好的,这是我遇到问题的代码片段(由于工作原因,类名已更改) const std::map&aMap=ot->getAMap(); A*A=getAFromSomewhere(); B*B=aMap[a]。秒//编译错误指向的行。 错误:操作“const std::map[A*]”是非法的 有人知道为什么会这样吗?类std::map的下标运算符声明如下 T& operator[](const key_type& x); T& operator[](key_type&

好的,这是我遇到问题的代码片段(由于工作原因,类名已更改)

const std::map&aMap=ot->getAMap();
A*A=getAFromSomewhere();
B*B=aMap[a]。秒//编译错误指向的行。
错误:操作“
const std::map[A*]
”是非法的


有人知道为什么会这样吗?

std::map
的下标运算符声明如下

T& operator[](const key_type& x);
T& operator[](key_type&& x);
正如您所看到的,它是为类的非常量对象声明的,因为如果映射中没有具有给定键的对象,那么它是由操作符创建的

由于恒定的引用,对象是恒定的

const std::map<A*, std::pair<int, B*> > &aMap = ot->getAMap();
^^^^^

如果您有一个不支持C++ 2011的旧编译器,那么您可以使用成员函数<代码>查找< /COD> .< /P> < P>类<代码>下标操作符::MAP< /Cord>声明为

T& operator[](const key_type& x);
T& operator[](key_type&& x);
正如您所看到的,它是为类的非常量对象声明的,因为如果映射中没有具有给定键的对象,那么它是由操作符创建的

由于恒定的引用,对象是恒定的

const std::map<A*, std::pair<int, B*> > &aMap = ot->getAMap();
^^^^^

如果你有一个旧的编译器不支持C++ 2011,那么你可以使用成员函数<代码>查找< /C> > .< > >代码> AMAP是const,但是<>代码>:ST:::运算符[]/Co>是非const成员函数(重载),它不能被调用const对象。 将其与非常量对象一起使用将起作用,例如

std::map<A*, std::pair<int, B*> > aMap = ot->getAMap(); // aMap is non-const, copied from the returned map
A *a = getAFromSomewhere();
B *b = aMap[a].second;
std::map aMap=ot->getAMap();//aMap为非常量,从返回的映射复制
A*A=getAFromSomewhere();
B*B=aMap[a]。秒;

aMap
是常量,但
std::map::operator[]
是非常量成员函数(重载),不能对常量对象调用

将其与非常量对象一起使用将起作用,例如

std::map<A*, std::pair<int, B*> > aMap = ot->getAMap(); // aMap is non-const, copied from the returned map
A *a = getAFromSomewhere();
B *b = aMap[a].second;
std::map aMap=ot->getAMap();//aMap为非常量,从返回的映射复制
A*A=getAFromSomewhere();
B*B=aMap[a]。秒;


这是因为它不是有效的C++。代码> B*<代码>无效C++。对不起,我不明白为什么你说它无效。AMAP[A]应该返回对,第二个应该访问B*,因为它不是。根据C++语言的规范,它是无效的。这不是有效的C++。如果是这样,就不会得到编译错误。这是因为它不是有效的C++。代码> B*<代码>无效C++。对不起,我不明白为什么你说它无效。AMAP[A]应该返回对,第二个应该访问B*,因为它不是。根据C++语言的规范,它是无效的。这不是有效的C++。如果是,则不会得到编译错误。但是get getAMap()返回一个const std::map&类型。那么我的aMap也应该是常量吗?@Mox那么你不能直接在返回的地图上调用
操作符[]
。您可以复制一份,然后像我的示例所示那样调用
operator[]
,或者像@ladfromMoscow那样使用
at()
;但请注意,它的行为与
操作符[]
不同。这取决于您的需要,如果您不想在密钥不存在的情况下插入值,那么您应该使用
at()
而不是
operator[]
。我将给您的解决方案一个机会=)很抱歉再次打扰您,请回答一个与您的解决方案和vlad相关的快速问题。虽然urs创建了一个新副本(我假设),但查找对象的复杂性为O(logn),而Vlad的find运行时间为O(N),这是更推荐的方法?@Mox如果您只想从map中获取元素,那么应该使用
std::map::find()
,它也是O(logn)。但是get getAMap()返回常量std::map&类型。那么我的aMap也应该是常量吗?@Mox那么你不能直接在返回的地图上调用
操作符[]
。您可以复制一份,然后像我的示例所示那样调用
operator[]
,或者像@ladfromMoscow那样使用
at()
;但请注意,它的行为与
操作符[]
不同。这取决于您的需要,如果您不想在密钥不存在的情况下插入值,那么您应该使用
at()
而不是
operator[]
。我将给您的解决方案一个机会=)很抱歉再次打扰您,请回答一个与您的解决方案和vlad相关的快速问题。虽然urs创建了一个新副本(我假设),但查找对象的复杂性为O(logn),而Vlad的查找运行时间为O(N),这是更推荐的方法?@Mox如果您只想从map中获取元素,您应该使用
std::map::find()
,它也是O(logn)。@Mox根本没有。我们,初学者,应该互相帮助。:)不幸的是,我不能使用at(),因为我这里的编译器比它旧。因此,只有C++98可用于me@Mox请参阅我的更新帖子。感谢您的更新,这也回答了我的问题,即我的同事为什么在代码中使用find@莫克斯也许他当时已经问了一个类似的问题,不是吗?:)@Mox根本没有。我们,初学者,应该互相帮助。:)不幸的是,我不能使用at(),因为我这里的编译器比它旧。因此,只有C++98可用于me@Mox请参阅我的更新帖子。感谢您的更新,这也回答了我的问题,即我的同事为什么在代码中使用find@莫克斯也许他已经问了一个类似的问题,不是吗?:)