Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ GDB:包含STL容器的漂亮打印类_C++_Stl_Gdb_Pretty Print_Gdb Python - Fatal编程技术网

C++ GDB:包含STL容器的漂亮打印类

C++ GDB:包含STL容器的漂亮打印类,c++,stl,gdb,pretty-print,gdb-python,C++,Stl,Gdb,Pretty Print,Gdb Python,我试图为一个包含std::对象集的类编写一个漂亮的打印机,我也为这个类提供了自己的漂亮打印机。基本上,这就是我的C++代码的样子: #include <set> #include <iostream> #include <cassert> class Foo { public: int x; bool operator<(const Foo & rhs) const { return this->x < rhs.x

我试图为一个包含std::对象集的类编写一个漂亮的打印机,我也为这个类提供了自己的漂亮打印机。基本上,这就是我的C++代码的样子:

#include <set>
#include <iostream>
#include <cassert>

class Foo {
public:
  int x;

  bool operator<(const Foo & rhs) const {
    return this->x < rhs.x;
  }
};

class FooContainer {
public:
  std::set<Foo> content;
};

int main(int argc, char **argv) {
  FooContainer c;
  Foo f1 {1};
  Foo f2 {2};
  c.content.insert(f1);
  c.content.insert(f2);

  assert(false); // hand over to gdb
}
但是,尝试这些,GDB会给我一个错误:

(gdb) p c 
Python Exception <class 'TypeError'> 'gdb.Value' object is not iterable: 
$7 =
(gdb)p c
Python异常“gdb.Value”对象不可编辑:
$7 =

看起来FooContainerPrinter只能访问std::set的内部成员,不能对其进行迭代。我真的不想亲自穿过那棵树后面的红黑树。有什么巧妙的方法可以做到这一点吗?

没有什么好方法可以完全做到你想要的。主要的问题是,pretty printing API故意保持简单(可以说有点过于简单),因此它没有提供一种可编程的方式来分离容器——它只提供打印所需的内容,这有时不太通用

但是,在这种情况下,一种可行的方法可能是使用
std::set
打印机

也就是说,只需放下
Foo容器
打印机,然后编写一台
Foo
打印机。
FooContainer
将使用默认gdb样式打印,附带的
std::set
将使用libstdc++打印机显示,单个元素将使用
Foo
打印机显示


但是,如果您真的想将整个内容打印为一个长字符串,那么恐怕您必须挖掘
std::set
打印机并从中提取一些代码。

经过一些尝试,我找到了一种非常接近的方法。我基本上使用的是stdlib附带的默认StdSetPrinter,但我不是用它来打印,只是用来迭代集合。我的代码现在看起来像这样:

from libstdcxx.v6.printers import StdSetPrinter

class FooPrinter(object):
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return "X: " + str(self.val['x'])

class FooContainerPrinter(object):
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return "My Foo Container"

    def children(self):
        pp = StdSetPrinter("dummy", self.val['content'])
        return pp.children()
现在,默认的pretty printing magic仍然添加了一些样板文件(基本上它输出“My Foo Container={…&langle;pretty print of the contents&rangle;…}”),但这对我来说没什么问题。我认为它甚至可以不定义自己的children(),而是将pp.children()内部用于_string(),从而完全控制输出字符串


它有一个缺点,libstdc++放置默认漂亮打印机的路径需要在PYTHONPATH中。

关于Tom的最后一点,请参阅
RbtreeIterator
类型(它将GCC的RB树转换为树中所有节点上的Python iterables)以及
get\u value\u from\u Rb\u tree\u node
函数,该函数按其名称执行。您可能不需要从它们中提取代码,只需重用它们。我希望如此。这是一个好主意,但需要注意的是,如果libstdc++发生变化,您的代码将来可能需要进行调整。我忘了这段代码使用了一个方便的助手类…谢谢你的回答。然而,我想我找到了一种方法,通过劫持默认的漂亮打印机来做我想做的事情。有关详细信息,请参阅我的答案。
from libstdcxx.v6.printers import StdSetPrinter

class FooPrinter(object):
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return "X: " + str(self.val['x'])

class FooContainerPrinter(object):
    def __init__(self, val):
        self.val = val

    def to_string(self):
        return "My Foo Container"

    def children(self):
        pp = StdSetPrinter("dummy", self.val['content'])
        return pp.children()