基于范围的二维地图for循环



我有一个像这样声明的二维映射:

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_objectivesconst

operator[]不能在const映射上工作,因为它被定义为在没有找到键时修改映射。

这就是你的误差。注意,如果它以某种方式修改了映射,则外部循环将被搞砸,因此映射是const是幸运的。正如您所注意到的,在这种情况下,它实际上不会修改它(因为您正在从它自己反馈键)。

无论如何,[]将是低效的,因为当您在那里有值部分时,它会生成额外的映射查找。

修复方法很简单:

for (auto const &subject : m_objectives) {
  for (auto const &objective : subject.second) {
    //Print the objective
  }
}

这是正确的(因为它没有在const map上使用[]),而且更快(因为如果你以某种方式取消const - map - m_objectives,使用[]在迭代映射时既低效又容易出错)。

相关内容

  • 没有找到相关文章

最新更新