我有一个像这样声明的二维映射:
typedef std::map<std::string, std::map<std::string, Objective>> objectives_t;
我想把这个2d地图的内容保存到一个文件中。
所以我尝试了一些类似的东西,灵感来自于我在网上找到的一些代码:
for (auto const &subject : m_objectives) {
for (auto const &objective : m_objectives[subject.first]) {
//Print the objective
}
}
当然,这行不通。我该怎么做呢?我真的不确定什么是主体和客体(它们是一些迭代器吗?)在第二行,我得到:
error: passing 'const objectives_t {aka const std::map<std::basic_string<char>, std::map<std::basic_string<char>, Objective> >}' as 'this' argument of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = std::basic_string<char>; _Tp = std::map<std::basic_string<char>, Objective>; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, std::map<std::basic_string<char>, Obj|
您的外循环是正确的。但内部应该是在subject.second
for (auto const &subject : m_objectives) {
for (auto const &objective : subject.second) {
// print out objective.second
}
}
这是因为在第一个基于范围的for循环之后,subject
具有类型
std::pair<const std::string, std::map<std::string, Objective>> const&
所以每一项都是
subject.first // std::string
subject.second // std::map<std::string, Objective>
然后当你迭代subject.second
时,你的objective
现在是
std::pair<const std::string, Objective> const&
再次将元素分开
objective.first // std::string
objective.second // Objective
上述代码中的m_objectives
为const
。
operator[]
不能在const
映射上工作,因为它被定义为在没有找到键时修改映射。
这就是你的误差。注意,如果它以某种方式修改了映射,则外部循环将被搞砸,因此映射是const是幸运的。正如您所注意到的,在这种情况下,它实际上不会修改它(因为您正在从它自己反馈键)。
无论如何,[]
将是低效的,因为当您在那里有值部分时,它会生成额外的映射查找。
修复方法很简单:
for (auto const &subject : m_objectives) {
for (auto const &objective : subject.second) {
//Print the objective
}
}
这是正确的(因为它没有在const map
上使用[]
),而且更快(因为如果你以某种方式取消const
- map
- m_objectives
,使用[]
在迭代映射时既低效又容易出错)。