QMap::insert报错:传递const QString作为this参数丢失限定符及const使用咨询
const修饰符使用误区与QMap编译错误解析
问题背景
开发XmlReader时对const修饰符的使用场景不明确,习惯在所有能加的地方都添加const,编写了一段读取XML属性的代码后出现编译错误。已知QVector无法包含const对象,不确定QMap是否支持存储const类型元素。
原代码
const QMap<const QString, const QString> XmlElement::readDomAttributes( const QDomElement& domElement) const { QMap<const QString, const QString> attributes; const QDomNamedNodeMap& domAttributes = domElement.attributes(); for (size_t size = domAttributes.size(), i = 0; i < size; ++i) { const QDomAttr& domAttribute = domAttributes.item(i).toAttr(); attributes.insert(domAttribute.name(), domAttribute.value()); } return attributes; }
编译错误信息
/src/xml-element.cpp:21: error: passing ‘const QString’ as ‘this’ argument discards qualifiers [-fpermissive] In file included from /usr/include/qt/QtCore/QMap:1, from ../../include/xml-element.h:4, from ../../src/xml-element.cpp:1: /usr/include/qt/QtCore/qmap.h: In instantiation of ‘QMap<K, V>::iterator QMap<K, V>::insert(const Key&, const T&) [with Key = const QString; T = const QString]’: ../../src/xml-element.cpp:21:26: required from here /usr/include/qt/QtCore/qmap.h:730:25: error: passing ‘const QString’ as ‘this’ argument discards qualifiers [-fpermissive] 730 | lastNode->value = avalue; | ~~~~~~~~~~~~~~~~^~~~~~~~
错误原因解析
- QMap不支持存储const类型的键或值:Qt的容器(包括QMap、QVector等)内部需要对元素进行赋值、移动等操作,而const修饰的对象无法被修改。在
insert方法执行时,QMap内部会尝试给节点的value赋值,这就会触发“丢弃const限定符”的错误。和QVector一样,所有Qt容器都不支持存储const类型元素。 - 冗余的const修饰:给QMap的模板参数加
const是多余的,QMap的insert方法本身就接受const Key&和const T&参数,已经保证了传入的对象不会被修改,无需再将容器的键值类型设为const。
修正后的代码
const QMap<QString, QString> XmlElement::readDomAttributes( const QDomElement& domElement) const { QMap<QString, QString> attributes; const QDomNamedNodeMap& domAttributes = domElement.attributes(); for (size_t size = domAttributes.size(), i = 0; i < size; ++i) { const QDomAttr& domAttribute = domAttributes.item(i).toAttr(); attributes.insert(domAttribute.name(), domAttribute.value()); } return attributes; }
const正确使用场景总结
- 成员函数后的const:标识该成员函数不会修改类的成员变量,适合只读操作,你这里的用法是正确的。
- 函数参数的const引用:当函数不需要修改传入参数时,用
const Type&可以避免拷贝开销,同时保证参数不被修改,比如const QDomElement&、const QDomNamedNodeMap&的用法都没问题。 - 局部变量的const:如果局部变量的值不需要修改,可以加const,但容器内部的元素不能用const,因为容器需要对元素进行内部操作。
- 返回值的const:返回容器对象时,
const QMap<...>的意义不大,因为临时对象默认不可修改,但保留也不会出错,可根据个人习惯选择。
学习资料推荐
- 《C++ Primer》(中文版):有专门章节系统讲解const的各种用法,包括const对象、const成员函数、const引用等,是入门的核心资料。
- Qt官方文档:查看Qt容器类的说明文档,里面会明确标注容器支持的元素类型,避免类似的使用误区。
- 《Effective C++》:其中条款3(尽可能使用const)、条款4(确保对象在使用前已初始化)等内容,深入讲解const的正确使用时机,帮助建立良好的编程习惯。
内容的提问来源于stack exchange,提问作者Николай Авилкин
相关产品推荐
相关产品推荐

