C ++模板元编程 - 是否可以输出生成的代码?

时间:2009-08-02 14:29:02

标签: c++ templates metaprogramming seqan

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

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

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

5 个答案:

答案 0 :(得分:24)

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

通常的解决方案是使用静态断言和其他测试来填充代码,以验证正确的模板是否以正确的方式实例化。

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

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

当编译器遇到这个时,它会打印出一个漂亮而简单的错误消息“无法将<long, detailed typename>转换为int ***”,这样您就可以轻松验证模板参数T实际上是键入你认为它应该是。

答案 1 :(得分:22)

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

答案 2 :(得分:14)

检查my publication on C++ template metaprogram debugging

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

我已经整理了一个可以放置断点等的Visual C ++插件,但它相当于概念验证,而不是每天使用的工具。

我们一直致力于一个显示所有实例化的图形前端,允许调试,分析。不幸的是,我们无法承诺该工具的任何发布日期,因为我们在非常有限的空闲时间内这样做。

更新:调试器和分析器可用here

更新:C++Now presentation

答案 3 :(得分:5)

这可能是您问题的答案:

C++ Template preprocessor tool

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

答案 4 :(得分: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;

}

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

以下是调试器显示的内容:

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

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

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

希望有所帮助,
Ovanes