C++ const成员函数返回非const引用编译错误解决及原理咨询
std::map常量访问问题的解决与错误解析
编译错误信息
./test.cpp: In member function ‘std::map<int, mapValue>& myClass::getMap() const’: ./test.cpp:22:49: error: binding reference of type ‘std::map<int, mapValue>&’ to ‘const std::map<int, mapValue>’ discards qualifiers 22 | map<key, mapValue> &getMap() const { return m; } |
原始代码
#include <string> #include <map> #include <iostream> using namespace std; struct mapValue { int num; string data; }; class myClass { public: typedef int key; void adjustMap(int index, mapValue mv) { m[index] = mv; } map<key, mapValue> &getMap() const { return m; } private: map<key, mapValue> m = { {0, {0, "Hi!"}}, {1, {0, "Hello"}}, {2, {1, "Goodbye"}} }; }; void operateWithMapData(const myClass &c) { const auto &m = c.getMap(); for(auto &kv : m) { cout << kv.first << ":" << kv.second.data << ":" << kv.second.num << endl; } } int main() { myClass c; c.adjustMap(5, {8, "Bye"}); operateWithMapData(c); return EXIT_SUCCESS; }
1. 正确实现需求的方法
要保证operateWithMapData中无法修改map,同时保留类内部对map的修改能力,只需修改getMap()的返回类型为const引用,并保留成员函数的const修饰:
const map<key, mapValue>& getMap() const { return m; }
如果需要在其他场景下获取map的可变引用(比如类的非const对象需要修改map),可以重载一个非const版本的getMap():
// 非const对象调用,返回可变引用 map<key, mapValue>& getMap() { return m; } // const对象调用,返回const引用,保证不可修改 const map<key, mapValue>& getMap() const { return m; }
这样做的好处:
const myClass&对象调用getMap()时,只能拿到const引用,无法修改map的内容,完全符合operateWithMapData的需求- 非const的
myClass对象可以通过重载的非const版本获取可变引用,正常修改map - 无论哪种情况都避免了map的拷贝,保证效率
2. 编译错误的详细解释
这个错误的核心是const成员函数的特性与引用类型不匹配:
- 成员函数后面加
const,意味着这个函数不会修改类的任何成员变量,在函数内部,所有成员变量都会被自动视为const类型(这里的m会被当成const map<key, mapValue>) - 你试图返回的是
map<key, mapValue>&(非const引用),这相当于把一个const对象绑定到非const引用上——C++不允许这种操作,因为这样通过引用就能修改原本被承诺为不可变的对象,直接违反了const成员函数的语义 - 编译器报错里的“discards qualifiers”,就是指你试图丢弃
m的const限定符,把它转换成非const类型,这是语法层面的非法操作
内容的提问来源于stack exchange,提问作者SailorCire
相关产品推荐
相关产品推荐

