类中print()方法遍历std::map报错:const_iterator无法转换为iterator
std::map遍历在类const成员函数中的迭代器错误解决
问题描述
之前单独遍历std::map没有问题,但在类的print()方法中遍历map时出现迭代器类型转换错误,错误出现在迭代器实例化阶段。
报错信息
error: conversion from ‘std::map<std::__cxx11::basic_string<char, bool>>::const_iterator’ {aka ‘std::_Rb_tree_const_iterator<std::pair<const std::__cxx11::basic_string, bool>>’} to non-scalar type ‘std::map<std::__cxx11::basic_string<char, bool>>::iterator’ {aka ‘std::_Rb_tree_iterator<std::pair<const std::__cxx11::basic_string, bool>>’} requested 33 | for (map<string, bool>::iterator i = jobs.begin(); i != jobs.end(); i++) {
问题代码
class Employee { private: string name; map<string, bool> jobs; public: Employee() { name = ""; jobs[""] = false; } Employee(const Employee &other) { cout << "Copied." << endl; name = other.name; jobs = other.jobs; } Employee(string name, string task, bool trained) { this->name = name; jobs[task] = trained; } void setTask(string task, bool trained) { jobs[task] = trained; } void print() const { for (map<string, bool>::iterator i = jobs.begin(); i != jobs.end(); i++) { pair<string, bool> jobs = *i; cout << name << " is trained on " << jobs.first << "? " << jobs.second << endl; } } };
错误原因与解决方法
核心原因
print()是const成员函数,在const函数内部,类的成员变量会被视为const类型。因此jobs.begin()返回的是map<string, bool>::const_iterator(只读迭代器),但代码中用map<string, bool>::iterator(可写迭代器)去接收,这两种迭代器无法隐式转换,导致报错。
解决方法
方法1:改用const_iterator
将迭代器类型替换为const_iterator,配合.cbegin()/.cend()明确获取只读迭代器,同时用引用避免不必要的拷贝:
void print() const { for (map<string, bool>::const_iterator i = jobs.cbegin(); i != jobs.cend(); ++i) { const pair<const string, bool>& job = *i; cout << name << " is trained on " << job.first << "? " << boolalpha << job.second << endl; } }
注:map的元素本质是pair<const string, bool>,key是不可修改的,因此用const pair<const string, bool>&更符合只读逻辑。
方法2:使用范围for循环(更简洁)
C++11及以上支持范围for循环,会自动推导适配的迭代器类型,代码更简洁易读:
void print() const { for (const auto& job : jobs) { cout << name << " is trained on " << job.first << "? " << boolalpha << job.second << endl; } }
auto会自动推导为const pair<const string, bool>&,完美适配const环境,无需手动处理迭代器类型。
另外,不建议去掉print()的const修饰——print是只读操作,保留const能保证成员变量不被意外修改,符合代码设计逻辑。
内容的提问来源于stack exchange,提问作者David Shorten
相关产品推荐
相关产品推荐

