缺少模板特化
在某些情况下,可能需要为特定类型(或类型集)提供与泛型不同的模板实现。例如,通常需要为指针或数组准备一个特殊版本的 swap 函数。在这种情况下,C++ 允许您执行所谓的模板特化,即定义一个模板版本,其中泛型类型参数 T 被所需的具体类型替换。
在特化函数和方法模板时,必须为所有参数指定特定类型。这称为完全特化。
对于 C++ 对象类型模板,特化可以是完全特化,也可以是偏特化:它仅指定部分参数的类型(其余参数的类型将在模板实例化时推断或指定)。可以存在多个偏特化:唯一的条件是每个特化必须描述唯一的类型组合。
遗憾的是,MQL5 中没有完全意义上的特化。
模板函数特化与重载并无二致。例如,给定以下模板 func:
template<typename T>
|
它允许以以下形式之一为给定类型(例如 string)提供其自定义实现:
// explicit specialization
|
或:
// normal overload
|
只能选择其中一种形式。否则,我们会收到编译错误“'func' - 函数已定义且具有主体”。
关于类的特化,从那些为部分模板参数指定了具体类型的模板进行继承,可以被看作是这些模板偏特化的一种等价实现。模板方法可以在派生类中被重写。
以下示例 (TemplatesExtended.mq5) 展示了将模板参数用作父类型的几种方案,包括将其中一个参数指定为特定类型的情况。
#define RTTI Print(typename(this))
|
我们将使用变量根据模板实例化对象:
Derived2<Derived1<Base>> derived2; |
使用 RTTI 宏进行调试类型日志记录会产生以下结果:
Base
|
在开发以封闭二进制形式提供的 库 时,必须确保针对未来的库用户预期使用的所有类型,显式实例化模板。您可以通过显式地调用函数模板,并在某些辅助函数中(例如,这些函数可以绑定到全局变量的初始化)使用具体的类型参数来创建对象,从而实现此目的。