自动计算TMP中实例化类的数量?

时间:2012-07-09 21:26:29

标签: c++ templates counter instantiation template-meta-programming

给定模板元程序(TMP),C ++编译器是否会生成计算实例化类数的构建统计信息?或者有没有其他方法可以自动获取此号码?因此对于例如对立的因子

#include <iostream>

template<int N> struct fact { enum { value = N * fact<N-1>::value }; };
template<> struct fact<1> { enum { value = 1 }; };

int main()
{
    const int x = fact<3>::value;
    std::cout << x << "\n";
    return 0;
}

我想取回数字3(因为事实&lt; 3&gt;,事实&lt; 2&gt;,并且事实&lt; 1&gt;被实例化)。这个例子当然是微不足道的,但每当你开始使用例如Boost.MPL,编译时间真的爆炸了,我想知道有多少是由于隐藏的类实例化。我的问题主要是针对Visual C ++,但是gcc的答案也会受到赞赏。

编辑:我目前非常脆弱的Visual C ++方法是从Stephan T. Lavavej的videos / d1reportAllClassLayout之一添加编译开关,并对输出文件执行grep +字数统计,但它(a)极大地增加了编译时间,并且(b)正则表达式很难100%正确。

3 个答案:

答案 0 :(得分:8)

我向GCC创建了一个one-line change,使其在实例化时打印出每个类模板的名称。您可以直接调用C ++前端cc1plus而不使用-quiet标志来获取功能模板的相同内容。

我还没有把它变成一个合适的GCC选项,它只是我自己的源代码树上的黑客攻击。我正在考虑将其作为插件实现,但它并不在我的TODO列表顶部附近。

答案 1 :(得分:2)

当然,没有可移植的方式来做到这一点。

对于大多数编译器来说,有很多方法可以做到这一点。你已经为MSVC找到了一个。对于gcc,你可以使用gccxml。或者,对于任何开源编译器(gcc或clang),在实例化时添加代码应该非常简单,这些代码要么保持计数,要么记录在编译完成后可以过滤的东西。

对于Clang / LLVM,你可以构建一个挂钩实例的插件,这个实例更清晰,但实际上可能更多工作。

带有调试符号的构建,没有优化,也没有剥离可能最终会导致每个实例化的错位名称,您可以使用这些名称。但是,一些编译器(包括gcc)总是至少内联一些方法,无论你是否想要它们。如果您愿意修改代码,可能会强制它生成外部实例化,可能是这样的:

template<int N> struct fact { 
  enum { value = N * fact<N-1>::value }; 
  int *dummy() { return &fact<N-1>::value; }
};

答案 2 :(得分:1)

Steven Watanabe编写的工具可用于计算模板实例的数量。你可以得到它here。基本上,它会修改代码,以便每次实例化类时都会生成编译器警告,然后您可以使用正则表达式处理生成的文本。