【问题标题】:Inspecting the content of a map while debugging在调试时检查地图的内容
【发布时间】:2012-12-04 10:27:42
【问题描述】:

为了调试,我需要查看地图的内容(std::unordered_mapstd::map),Eclipse CDT 调试器没有以可读的形式提供给我,例如{1: 2, 3:4, ...}

在调试时检查地图内容的最佳方法是什么?

我必须回到使用打印语句进行调试吗?如果是,那么简洁的宏或函数将如何将任何地图的内容打印为字符串?

【问题讨论】:

  • Eclipse 中的调试器是 GDB,例如用于向 GDB 添加类型的 Google 搜索。
  • 没有给我可以理解的有用结果:bit.ly/T1XXYs

标签: c++ debugging map unordered-map


【解决方案1】:

我必须回到使用打印语句进行调试吗?如果是,那么简洁的宏或函数将如何将任何地图的内容打印为字符串?

我不知道你有没有 - 我不使用 Eclipse,但打印地图很容易:

template <typename K, typename V>
std::ostream& operator<<(std::ostream& os, const std::map<K, V>& m)
{
    os << "{ ";
    for (typename std::map<K, V>::const_iterator i = m.begin(); i != m.end(); ++i)
    {
        if (i != m.begin()) os << ", ";
        os << i->first << ": " << i->second;
    }
    return os << " }";
}

然后你可以使用&lt;&lt; my_map。请注意,尽管在大型代码库中,其他人可能会有相同的“聪明”想法,因此您可能希望将辅助函数放在您自己的命名空间中,或者给它一个更本地化的名称。诸如围绕"{ "" }"", " 分隔符的选择是任意的,可能不适合所有用户 - 有些人可能想要自动字符串引用/转义等,因此将其放在全局命名空间中会令人怀疑最好的时候,在这种情况下,它甚至可能被保留以备将来可能包含在 C++ 标准或其他东西中 - 毕竟,它有点喜欢将自己的名字添加到 std:: 命名空间中。如果您关心,请查看标准。

【讨论】:

  • 这将是一个解决方案,但是当我编译此代码时出现错误:/usr/local/Cellar/log4cxx/0.10.0/include/log4cxx/helpers/messagebuffer.h:190:47: error: cannot bind 'std::basic_ostream&lt;char&gt;' lvalue to 'std::basic_ostream&lt;char&gt;&amp;&amp;'
  • 使用C++11 range based for loops 更简单,例如this answer
  • @cls:您在此模板上没有得到匹配项,并且该错误来自另一个候选函数。如果您将它放在与调用代码不同的命名空间中,则不会找到它。您可以在要使用它的代码之前添加using Whatever_Namespace_It_Is_In::operator&lt;&lt;;
  • @JoachimPileborg:在循环控制和分离器测试中看到m.begin() 具有很好的一致性;鉴于 C++11,我只需将 typename std::map&lt;K, V&gt;::const_iterator 简化为 auto。对于基于范围的,您会推荐什么 - &amp;kv != &amp;*m.begin(),或单独的 bool first = true; ... if (first) first = false; else os &lt;&lt; ", " / size_t i = 0; ... if (i++)
【解决方案2】:

GDB 可以是extendedPython,还有pretty printing 的API。

many pretty printers for C++ available,比如this one

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-12-25
  • 1970-01-01
  • 1970-01-01
  • 2012-05-07
  • 1970-01-01
  • 2014-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多