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

时间:2017-09-13 19:45:24

标签: c++ c++11 gdb unordered-map

我有一个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"];

上面的两个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

使用gdb时,我没有遇到什么问题。

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

我使用以下语句生成可执行文件

gsrivas4@TitanX01:~/lcode1$ g++ -std=gnu++11 -O0 -g test1.cpp -o test1.out

1 个答案:

答案 0 :(得分:4)

您面临的问题是std::unordered_map<std::string,int>::at(key) 需要类型为std::string的键,而不是const char*文字的键。这意味着 您需要先创建一个临时的std :: string对象,然后再将其传递给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

因此,在没有GDB的情况下构造std::string对象似乎是不可能的 一些其他的C ++代码,因此只需添加到您的C ++代码中即可:

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

现在一切正常:

(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

但是

(gdb) p mymap[make_string("Jupiter")]
Could not find operator[].

这是行不通的,因为它从未实例化。您的代码实例化的方式:

std::cout<< mymap["Mars"];

T& operator[]( Key&& key );,很难从GDB调用。 如果您实例化了T& operator[]( const Key& key );,那么事情将会 情况更好。

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

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];
}

通过此操作,调试成为可能:

print mymap.at(make_string("Jupiter"))
print mymap[make_string("Jupiter")]

工作吧。