可变模板的可扩展性 [英] Scalability of variadic templates

查看:108
本文介绍了可变模板的可扩展性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用C ++ 11中的大型软件基础设施,广泛使用可变参数模板。我的问题如下:这种方法的可扩展性是什么?首先,可变参数模板可以采用的参数数量是否有上限?第二,代码膨胀是使用最先进的编译器的一个主要问题,当使用许多参数时(和扩展,这些参数的许多组合将产生模板方法的许多不同的实现)?

I am working on a large-scale software infrastructure in C++11 that makes extensive use of variadic templates. My question is the following: what is the scalability of this approach? First, is there an upper limit in the number of arguments that variadic templates can take? Second, is code bloat a major issue with state-of-the-art compilers when many arguments are used (and, by extension, many combinations of these arguments that would yield to many different implementations of the templated methods)?

推荐答案

我想我会去寻找是否有任何限制模板参数的数量为我的特定编译器(在Linux上为g ++ 4.8.1)。我使用了以下测试用例:

I thought I'd have a go at finding out whether there is any limit on the number of template parameters for my particular compiler (g++ 4.8.1 on Linux). I used the following test case:

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;
}

模板递归深度限制在g ++中默认为900,因此899参数看到。这个可笑的长结构名用于查看是否可以生成任何对于链接器处理太大的符号 - 在一秒钟内更多。

The template recursion depth limit defaults to 900 in g++, hence the 899 parameter you see. The ridiculously long struct name is used to see whether I could generate any symbols which were too big for the linker to handle -- more on this in a sec.

你不能看到测试用例中发生了什么,基本上每个实例化 A 创建一个成员变量,添加20个额外的模板参数。部分专门化用于停止递归。到最后, A <0,...> 在18000个模板参数的范围内。

In case you can't see what's going on in the test case, basically every instantiation of A creates a member variable which adds 20 extra template parameters. Partial specialisation is used to stop the recursion. By the end, A<0, ...> has somewhere in the region of 18000 template parameters.

我发现是g ++处理这个很好。花了很长时间来考虑它,并使用了相当的一点内存,但我不能简单地通过增加模板参数的数量使它失败。当模板递归深度被设置得足够大(即900)时,Clang 3.1也处理这个没有任何问题。

What I found was that g++ handled this just fine. It took quite a while to think about it, and used a fair bit of memory, but I was unable to get it to fail simply by increasing the number of template parameters. Clang 3.1 also handled this without any problem once the template recursion depth was set sufficiently (i.e. 900).

此外,虽然被破坏的符号名确实变得巨大,无法打破 nm ld 使用它们。 (值得注意的是,Linux / Itanium重构方案使用替换,以便重复相同类型的模板参数不重复整个类型名称,而是标记为 S0 S1 等)一个快速的google似乎没有对ELF符号长度的任何限制,但也许有人知道是否存在这样的限制。

Furthermore, although the mangled symbol names do indeed become huge, I was unable to break either nm or ld using them. (It's worth noting that the Linux/Itanium mangling scheme uses substitution so that repeated template parameters of the same type don't repeat the whole type name, but rather are marked S0, S1 etc.) A quick google doesn't seem to turn up any limit on ELF symbol length, but perhaps someone else knows whether such a limit exists.

总而言之,对于Linux上的g ++和clang,至少对模板参数数量没有任何实际限制

In conclusion then, for g++ and clang on Linux at least, there doesn't seem to be any practical limit on the number of template parameters.

至于问题的第二部分,关于代码膨胀,很难说,特别是一旦涉及到编译器优化。很容易用可变模板进行递归,但是编译器很容易去除中间类型。我只能建议试试看看。

As to the second part of your question, regarding code bloat, it's very hard to say, particularly once compiler optimisation gets involved. It's easy to do recursion with variadic templates, but then it's easy for the compiler to get rid of intermediate types too. I can only suggest to try it and see.

这篇关于可变模板的可扩展性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆