在gdb中使用带有unordered_map的[]运算符可以得到未解析的运算符

GAU*_*AVA 9 c++ gdb unordered-map c++11

我有一个C++代码,我在实例化一个unordered_map,然后使用cout打印它的值.这很好用.但是,当我尝试在gdb中运行它并打印unordered_map的值时,这给了我错误.下面是代码片段:

  std::unordered_map<std::string,int> mymap = {
                      { "Mars", 3000},
                      { "Saturn", 60000},
                      { "Jupiter", 70000 } };

    std::cout<< mymap.at("Mars");
    std::cout<< mymap["Mars"];
Run Code Online (Sandbox Code Playgroud)

上面的两个cout语句都打印了密钥"Mars"的unordered_map值.但是,当我使用gdb然后尝试使用以下语句在关键字"Mars"上打印mymap的值时,我会收到错误.

(gdb) print mymap.at("Mars")
Cannot resolve method std::unordered_map<std::basic_string<char, 
std::char_traits<char>, std::allocator<char> >, int, 
std::hash<std::basic_string<char, std::char_traits<char>, 
std::allocator<char> > >, std::equal_to<std::basic_string<char, 
std::char_traits<char>, std::allocator<char> > >, 
std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, 
std::allocator<char> > const, int> > >::at to any overloaded instance

(gdb) print mymap["Mars"]
Cannot resolve function operator[] to any overloaded instance
Run Code Online (Sandbox Code Playgroud)

我使用gdb时没有出错.

我已经尝试在gdb中使用whatis mymap来查看mymap是否存在于当前上下文中并且它表示它存在.此外,我尝试初始化一个int变量并在gdb中打印它并打印它.我不明白unordered_map有什么问题.

我使用下面的语句来生成可执行文件

gsrivas4@TitanX01:~/lcode1$ g++ -std=gnu++11 -O0 -g test1.cpp -o test1.out
Run Code Online (Sandbox Code Playgroud)

Mic*_*ler 9

您面临的问题是std::unordered_map<std::string,int>::at(key) 需要 type 的键std::string,而不是const char*文字。这意味着您希望在将其传递给at().

从 GDB 中创建临时对象对我来说效果不佳,我可能会遗漏一些东西,但这就是我得到的:

(gdb) p std::string("Mars")
A syntax error in expression, near `"Mars")'.
(gdb) p 'std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)'("Mars")
$9 = -161888904
Run Code Online (Sandbox Code Playgroud)

所以std::string在没有一些额外的 C++ 代码的情况下,在 GDB 中构造一个对象似乎是不可能的,所以只需添加到你的 C++ 代码中:

std::string make_string(const char *x)
{
        return x;
}
Run Code Online (Sandbox Code Playgroud)

现在一切正常:

(gdb) p mymap.at(make_string("Mars"))
$1 = (std::unordered_map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >::mapped_type &) @0x60005e5f0: 3000
(gdb) p mymap.at(make_string("Jupiter"))
[New Thread 14608.0x16f4]
$2 = (std::unordered_map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >::mapped_type &) @0x60005e650: 70000
Run Code Online (Sandbox Code Playgroud)

(gdb) p mymap[make_string("Jupiter")]
Could not find operator[].
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为它从未被实例化。您的代码实例化的内容:

std::cout<< mymap["Mars"];
Run Code Online (Sandbox Code Playgroud)

曾是 T& operator[]( Key&& key );这是棘手从GDB调用。如果你T& operator[]( const Key& key );改为实例化,那么事情会变得更好。

解决方案:实例化 operator[](const std::string &)在 C++ 代码中变体。所以这是新代码:

std::string make_string(const char *x)
{
        return x;
}

int main()
{
 std::unordered_map<std::string,int> mymap = {
                      { "Mars", 3000},
                      { "Saturn", 60000},
                      { "Jupiter", 70000 } };

    std::string mars{"Mars"};
    std::cout<< mymap.at(mars);
    std::cout<< mymap[mars];
}
Run Code Online (Sandbox Code Playgroud)

有了这个,调试成为可能:

print mymap.at(make_string("Jupiter"))
print mymap[make_string("Jupiter")]
Run Code Online (Sandbox Code Playgroud)

只是工作。