How do we extract/print individual values in an std::tuple?
Here is a sample program in a file named 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;
}
Compile it
g++ --std=c++11 -g test.cc
Run it in 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}
The last command printed the tuple as a whole. How can I extract individual values? My naives attempts fail.
(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".
Unfortunately, the pretty-printing code in gdb is a display-only feature -- so while it helps display a tuple in a nice way, it doesn't let you further access it.
The normal problem with something like t.get<0>
is that these tiny accessor methods are usually completely optimized away by the compiler -- so there is no copy to call. And, while gdb has an "xmethod" feature that can be used to supply gdb-side Python implementations of these accessors, info xmethods
shows (for me at least) that nobody has done this for std::tuple
yet.
So then you're pretty much left with just one option: inspecting the implementation. So, start by printing the raw 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>}
Here you can see the "real" structure of the tuple, and access the fields directly:
(gdb) print ((std::_Head_base<1ul, int, false>) t)._M_head_impl
$7 = 222
This cast to an intermediate type is kind of a pain, eh? It's needed to make gdb choose the correct _M_head_impl
field. If this is something you plan to do a lot I'd suggest writing that xmethod
. Or you could also easily write a Python convenience function to automate the access; this kind of introspection is a bit simpler to do with the Python API.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With