Gre*_*reg 18 c++ scalability variadic-templates c++11
我正在研究C++ 11中的大规模软件基础架构,它广泛使用可变参数模板.我的问题如下:这种方法的可扩展性是什么?首先,可变参数模板可以采用的参数数量是否有上限?其次,当使用许多参数时,代码膨胀是最先进的编译器的一个主要问题(并且,通过扩展,这些参数的许多组合将产生模板化方法的许多不同实现)?
Tri*_*dle 10
我想我可以找出我的特定编译器(Linux上的g ++ 4.8.1)的模板参数数量是否有任何限制.我使用了以下测试用例:
template <int I>
struct this_is_a_ridiculously_long_struct_name_youd_never_use_in_real_life {};
template <int Depth, typename... T>
struct A
{
using e = this_is_a_ridiculously_long_struct_name_youd_never_use_in_real_life<Depth>;
A() {};
A<Depth - 1, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, e, T...> a;
};
template <typename... T>
struct A<0, T...>
{
};
int main()
{
A<899> a;
}
Run Code Online (Sandbox Code Playgroud)
模板递归深度限制默认为900(以g ++为单位),因此您看到的是899参数.这个荒谬的长结构名称用于查看我是否可以生成任何对于链接器来说太大的符号 - 在一秒钟内更多.
如果您无法看到测试用例中发生的情况,基本上每个实例A
都会创建一个成员变量,该变量会添加20个额外的模板参数.部分特化用于停止递归.到最后,A<0, ...>
在某个地方有18000个模板参数.
我发现g ++处理这个很好.花了很长时间才考虑它,并使用了相当多的内存,但仅仅通过增加模板参数的数量,我无法让它失败.一旦模板递归深度设置得足够(即900),Clang 3.1也可以毫无问题地处理这个问题.
此外,虽然受损的符号名称确实变得很大,但我无法打破nm
或ld
使用它们.(值得注意的是,Linux/Itanium修改方案使用替换,以便相同类型的重复模板参数不重复整个类型名称,而是标记S0
,S1
等等.)快速谷歌似乎没有出现任何限制ELF符号长度,但也许其他人知道是否存在这样的限制.
总而言之,对于至少Linux上的g ++和clang ,模板参数的数量似乎没有任何实际限制.
至于你的问题的第二部分,关于代码膨胀,很难说,特别是一旦涉及编译器优化.使用可变参数模板进行递归很容易,但编译器也很容易摆脱中间类型.我只能建议尝试一下,看看.