GDB:我们如何从std :: tuple中提取值

时间:2016-07-22 13:40:15

标签: c++ c++11 gdb

我们如何在std :: tuple中提取/打印单个值?

以下是名为test.cc的文件中的示例程序。

#include <tuple>
#include <iostream>

 using namespace std;

 int main() {
     auto t = make_tuple(111, 222);
     cout << std::get<0>(t) << endl
          << std::get<1>(t) << endl;
     return 0;
 }

编译

g++ --std=c++11 -g test.cc

在gdb中运行

gdb --args ./a.out
...
(gdb) start
Temporary breakpoint 1 at 0x400836: file test.cc, line 7.
Starting program: /home/fmlheureux/a.out

Temporary breakpoint 1, main () at test.cc:7
7           auto t = make_tuple(111, 222);
(gdb) n
9                << std::get<1>(t) << endl;
(gdb) p t
$1 = std::tuple containing = {[1] = 111, [2] = 222}

最后一个命令将元组作为一个整体打印出来。如何提取单个值?我天真的尝试失败了。

(gdb) p get<0>(t)
No symbol "get<0>" in current context.
(gdb) p std::get<0>(t)
No symbol "get<0>" in namespace "std".

1 个答案:

答案 0 :(得分:5)

不幸的是,gdb中漂亮的打印代码只是一个显示功能 - 所以虽然它有助于以一种很好的方式显示元组,但它并不能让你进一步访问它。

t.get<0>这样的常见问题是这些微小的访问器方法通常被编译器完全优化 - 因此没有要调用的副本。而且,虽然gdb有一个&#34; xmethod&#34;可用于提供这些访问器的gdb端Python实现的功能,info xmethods显示(至少对我来说)还没有人为std::tuple执行此操作。

那么你只剩下一个选项了:检查实现。所以,首先打印原始元组:

(gdb) p/r t
$3 = {<std::_Tuple_impl<0ul, int, int>> = {<std::_Tuple_impl<1ul, int>> = {<std::_Head_base<1ul, int, false>> = {
        _M_head_impl = 222}, <No data fields>}, <std::_Head_base<0ul, int, false>> = {_M_head_impl = 111}, <No data fields>}, <No data fields>}

在这里你可以看到&#34;真实&#34;元组的结构,直接访问字段:

(gdb) print ((std::_Head_base<1ul, int, false>) t)._M_head_impl
$7 = 222

这种中间类型的演员是一种痛苦,嗯?需要让gdb选择正确的_M_head_impl字段。如果这是你计划做的事情,我建议你写xmethod。或者您也可以轻松编写Python便捷功能来自动访问;这种内省对Python API来说有点简单。