C++11 - 二维地图上基于范围的 for 循环
C++11 - Range-based for loop on a two-dimensional map
我有一张二维地图,我是这样声明的:
typedef std::map<std::string, std::map<std::string, Objective>> objectives_t;
我想将这张二维地图的内容保存到一个文件中。
所以我尝试了类似的东西,灵感来自我在网上找到的一些代码:
for (auto const &subject : m_objectives) {
for (auto const &objective : m_objectives[subject.first]) {
//Print the objective
}
}
当然,这行不通。我应该怎么做?我不太确定 subject 和 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
不知何故,在遍历地图时使用 []
既效率低下又容易出错。
我有一张二维地图,我是这样声明的:
typedef std::map<std::string, std::map<std::string, Objective>> objectives_t;
我想将这张二维地图的内容保存到一个文件中。
所以我尝试了类似的东西,灵感来自我在网上找到的一些代码:
for (auto const &subject : m_objectives) {
for (auto const &objective : m_objectives[subject.first]) {
//Print the objective
}
}
当然,这行不通。我应该怎么做?我不太确定 subject 和 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
不知何故,在遍历地图时使用 []
既效率低下又容易出错。