3

<>我使用 C++ 并计划了一个包含大约 100 个模板参数的类的库。当然,我担心有n个模板参数,如果用户需要每个组合,我们有2^n个不同的类,这是一种代码爆炸。但是,用户需要为此进行 2^n 次实例化。

我的问题是:这么多模板参数的主要技术问题是什么?

笔记:

  • 对于技术,我对关于可读性、设计等的主观答案不感兴趣。我的意思是像这样的事实
    • 运行
    • 代码大小
    • 允许的最大模板数

代码示例:

// here we have 2, but I have 100 template parameters
template<typename T1, typename T2>
class Class
{
    T1 x;
    T2 y;
    int add(T1 _x, T2 _y) { return _x+_y; } // 4 instanciations possible?
    Class<T2, T1>* swap() { return new Class<T2, T1>(); } // always 2 instanciations?
};
4

3 回答 3

4

实际上模板化的类类型是在编译时确定的。这并不意味着您有 2^n 个不同的课程,而是您只有 n 个课程。在编译时,适当的类型被替换并且类成员/函数只是您使用它们的类型。

例如

template <class Type1, class Type2>
class A
{
private:
    Type1 member_x;
public:
    Type2 GetTypeValue(Type1, Type2);
};

当像这样实例化时:

A<int, string> *x = new A<int, string>();

仅作为具有整数类型成员和字符串类型成员的类编译。同样代表功能等。

更新: 使用下面的更新示例,您仍然只有一个函数实例,它将是一个string带参数的返回函数intstring.

于 2012-09-27T11:51:31.333 回答
3

主要考虑因素是代码大小,这可能会对性能产生影响。每个不同的模板实例化都需要生成所有使用的成员函数(或全部,如果用户进行手动模板实例化)。不同的模板实例之间不会有代码重用。

除此之外,您提供大量参数的任何元素都很难处理。从维护的角度来看,带有 10 个参数的声明已经很难阅读。它要么延伸多行,要么在行中延伸得非常宽,并且很难通过检查来确定所有参数都在正确的位置。那 X 是第 7 个还是第 8 个参数?是的,你可以数一数,但它会变得很痛苦。如果参数的数量为 100,则问题只会更加严重。

为什么你希望所有这些都是模板参数?如果没有更多信息,您将不会得到其他建议,但很可能有针对同一问题的其他设计不需要这种复杂程度。也许在编译时不需要知道参数(它们可以以数组/向量的形式传递给函数/构造函数,用于非类型参数),或者它们可以被分组(一个类型模板参数包含一组相关的 typedef )...

于 2012-09-27T12:24:40.113 回答
1

这样做是有理由的。用于序列化、解析、文档、智能感知的自动代码生成器。所有标头都可以被解析,然后自动编写为第二个类,该类具有已解析类的每个成员函数的模板成员。由于自动代码系统将编写代码,因此可读性并不重要,但是您可以访问任何类成员,无论大小或基于每个模板成员的类型的某些分支代码的间接性,这是每个自动生成的基类模板类。

然后,在使用该类时,您可以通过查看类型来编写每个“类型”的函数,或者您可以将每个模板类型的值显示为解析器或 IDE 显示器的输出。粗略地说,智能将被完全预编译以实现快速搜索。只需有一个并行项目,它可以根据头文件中的更改进行编译,然后它可以查找各种特征,而不管它是什么类型的类成员。

从技术上讲,它从解析、记录、输出或显示类中的项目的整个问题中删除类型,并在查看某些文件的某些程序的编译时执行此操作。因为每个成员都有一种查看类型的方式(类似于为什么编译器更喜欢使用 static_cast 而不是 c 样式转换)

代码大小将与每个类解析 1-1 的文件大小相同,优势将是任何程序内存空间,可以转换为匹配它的自动写入类型,然后使用类型感知的函数访问以显示操作或输出值. 想象一下,如果简单地在某个文件中找到一个“类”,就可以方便地访问该类中的所有信息,而无需进行任何解析,只需要以模板形式转换到您预先创建的类,其中自动生成类的基类有方法来操作现在可检测类型的数据。

可能他在用 100 多个模板参数做什么

于 2020-06-15T02:21:17.237 回答