27

我想调试一些模板代码以更好地理解它。
不幸的是,我是模板元编程的新手,我很难进入。

当我尝试输出预处理的源文件时,我得到 125 000 行代码:/

那么有没有办法可以看到生成的代码?(我使用的库是SeqAn

4

5 回答 5

26

不,一般来说,它是做不到的。模板只是 C++ 语言的一部分,它们不是单独的预处理器,因此它们不会生成 C++ 代码。

通常的解决方案是在代码中添加静态断言和其他测试,以验证正确的模板是否以正确的方式实例化。

一旦您开始迷失在元编程中,这个简单的技巧可以帮助您确定模板参数的真正类型:

// given a variable t of an unknown type T
int*** i = t;

当编译器遇到这种情况时,它会打印出一个漂亮而简单的错误消息,“无法转换<long, detailed typename>为 int***”,让您轻松验证模板参数 T 是否实际上是您认为的类型。

于 2009-08-02T18:16:38.460 回答
24

不,不是。预处理器与模板处理无关,模板处理由编译器执行。模板不会生成 C++ 代码,就像函数调用一样 - 它们是 C++ 语言本身的一个组成部分。

于 2009-08-02T14:31:40.170 回答
15

查看我关于 C++ 模板元程序调试的出版物

从第 6 页您可以看到它是如何工作的。对于特定目的,您不需要整个工具链,可以手动完成。

我已经组装了一个 Visual C++ 插件,您可以在其中放置断点等,但它更像是概念验证,而不是日常使用的工具。

我们一直在开发一个图形前端,它显示所有实例化,允许调试和分析。不幸的是,我们不能保证该工具的任何发布日期,因为我们是在非常有限的空闲时间里做的。

UPDATE: the debugger and profiler is available here

UPDATE: C++Now presentation

于 2010-03-22T07:59:07.890 回答
6

这可能是您问题的答案:

C++ 模板预处理器工具

似乎已经满足了最后一个问的人 - 虽然我无法想象为什么!C 语言中的 C++ 编译器的输出通常很难阅读,因为它的目的不是帮助理解,而只是一种可移植的汇编语言。

于 2009-08-02T15:01:07.783 回答
1

一般来说,不可能输出整个代码。但我发现非常有趣的是能够使用 Visual C++ 调试器向您显示类型。以那个简单的元程序为例:

template<class Head, class Tail>
struct type_list
{
  typedef Head head;
  typedef Tail tail;
};

struct null_type
{};

template<class List>
struct list_head
{
  typedef typename List::head head;
};

template<class List>
struct list_tail
{
  typedef typename List::tail tail;
};

template<class List>
struct list_length
{
  static const size_t length = 1+list_length< typename list_tail<List>::tail >::length;
};

template<>
struct list_length<null_type>
{
  static const size_t length = 0;
};


int main()
{
  typedef 
    type_list
    < int
    , type_list
      < double
      , type_list
        < char
        , null_type
        >
      >
    >       my_types;

  my_types test1;

  size_t length=list_length<my_types>::length;

  list_head<list_tail<list_tail<my_types>::tail>::tail>::head test2;

}

我只是实例化了我的元类型。这些仍然是至少 1 个字节长的空 C++ 类实例。现在我可以在 test2 的最后一个实例化之后放置一个断点,然后查看 length、test1 和 test2 的类型/值:

这是调试器显示的内容:

length  3   unsigned int
test1   {...}   type_list<int,type_list<double,type_list<char,null_type> > >
test2   -52 'Ì' char

现在您知道 head 返回了一个字符,您的列表包含 int、double、char 并由 null_type 终止。

这对我帮助很大。有时您需要将真正凌乱的类型复制到文本编辑器并将其格式化为可读的形式,但这使您可以跟踪里面的内容以及计算方式。

希望有帮助,
欧文斯

于 2009-08-02T16:16:44.830 回答