给定模板元程序(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%正确。
答案 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。基本上,它会修改代码,以便每次实例化类时都会生成编译器警告,然后您可以使用正则表达式处理生成的文本。