2016-07-22 133 views
4

我们如何提取/打印std :: tuple中的单个值?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". 
+0

我的解决方案是使用'struct'而不是'tuple'。 gdb可以处理它。当然,实际上gdb应该只支持元组访问...... – TheJJ

回答

4

不幸的是,在gdb漂亮的打印代码是一个只显示的功能 - 所以当它有助于显示一个不错的方式一个元组,它不会让你再访问它。

t.get<0>类似的正常问题是,这些微小的访问器方法通常会被编译器完全优化掉 - 因此没有要调用的副本。而且,虽然gdb具有“xmethod”功能,可用于提供这些访问器的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>} 

在这里你可以看到元组的“真实”的结构,并直接访问领域:

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

这种强制转换为中间型是一种因此,通过打印原始元组开始痛苦,呃?需要让gdb选择正确的_M_head_impl字段。如果这是你打算做很多事情,我会建议你写这个xmethod。或者你也可以轻松地编写一个Python便利函数来自动化访问;这种内省对于Python API来说更简单一些。

+1

感谢您的解决方案!对于未来的读者,我想指出'1ul'是元组内的索引。 –