免责声明:该文章始于2月,但由于取决于我的原因,它尚未完成。 主题非常广泛,因此以截短的形式发布。 不合适的内容将在以后考虑。

不知道什么编程模式是不可能理解现代C ++的。 语言的这种特性为优化和重用代码提供了广泛的可能性。 在本文中,我们将尝试弄清它是什么以及它们如何工作。
C ++中的模板机制使我们能够解决将各种类型的算法统一的问题:无需为整数,实数或用户类型编写不同的函数-只需基于通用属性即可编译不依赖于数据类型的通用算法就足够了。 例如,排序算法既可以使用整数也可以使用“汽车”类型的对象。
有功能模板和类模板。
功能模板是对功能行为的一般描述,可以为不同类型的对象调用这些功能。 换句话说,功能模板(模板功能,通用功能)是一系列不同的功能(或算法的描述)。 通过描述,函数模板类似于常规函数:区别在于某些元素未定义(类型,常量)并且已参数化。
类模板 -用户类型的通用描述,可以在其中对属性和类型操作进行参数化。 它们是通过替换具体参数而不是参数可以生成实际类的构造。
让我们更详细地考虑功能模板。
功能模板
如何编写第一个模板函数?
考虑确定两个最小元素的情况。 对于整数和实数,您将必须编写2个函数。
int _min(int a, int b){ if( a < b){ return a; } return b; } double _min(double a, double b){ if( a < b){ return a; } return b; }
当然,您只能使用有效参数来实现一个功能,但是对于理解模式而言,这将是有害的。
如果应用程序被编译会怎样? 该函数的两个实现都将落入应用程序的二进制代码中,即使它们不被使用(但是,现在的编译器非常聪明,他们知道如何切出未使用的代码)。 并且,如果您需要添加一个定义至少两行的函数(很难想象如果不指定至少有两行)?
在这种情况下,如果该算法对于必须使用的类型是通用的,则可以定义功能模板。 一般情况下,该原则如下:
- 对某种类型采用函数实现;
- 头模板<class Type>(或模板<typename Type>)已分配,这意味着算法使用某种抽象Type。
- 在函数的实现中,类型名称由Type代替。
对于min函数,我们得到以下信息:
template<class Type> Type _min(Type a, Type b){ if( a < b){ return a; } return b; }
最有趣的事实是,虽然没有调用min函数,但是在编译时,它不是用二进制代码创建的(未
实例化的 )。 而且,如果您声明一组带有各种类型变量的函数调用,则每个编译器都会基于模板创建自己的实现。
调用模板函数通常等效于调用普通函数。 在这种情况下,编译器将根据实际参数的类型确定使用哪种类型而不是Type。 但是,如果替换参数的类型不同,则编译器将无法输出(实例化模板)模板的实现。 因此,在下面的代码中,编译器将在第三个调用时遇到问题,因为它无法确定类型是什么(想想为什么?):
#include <iostream> template<class Type> Type _min(Type a, Type b) { if (a < b) { return a; } return b; } int main(int argc, char** argv) { std::cout << _min(1, 2) << std::endl; std::cout << _min(3.1, 1.2) << std::endl; std::cout << _min(5, 2.1) << std::endl; // oops! return 0; }
通过在调用函数时指定特定的类型可以解决此问题。
#include <iostream> template<class Type> Type _min(Type a, Type b) { if (a < b) { return a; } return b; } int main(int argc, char** argv) { std::cout << _min<double>(5, 2.1) << std::endl; return 0; }
模板功能(不)什么时候起作用?
原则上,您可以理解编译器只是在模板中替换了所需的类型。 但是生成的功能将始终有效吗? 显然不是。 可以定义任何算法,而与数据的类型无关,但是必须使用该数据的属性。 对于模板函数_min,这是定义排序运算符(operator <)的要求。
根据实现的不同,任何函数模板都假定存在参数化类型的某些属性(例如,复制运算符,比较运算符,特定方法的存在等)。 在预期的C ++语言标准中, 概念将为此负责。功能模板重载
功能模板也可以重载。 通常在以下情况下执行此重载
template<class Type> Type* _min(Type* a, Type* b){ if(*a < *b){ return a; } return b; }
特殊情况
在某些情况下,功能模板对于特定类型无效或不正确。 在这种情况下,您可以
专门化模板,即为该类型编写一个实现。 例如,对于字符串,您可能希望函数仅比较字符数。 对于功能模板的专用化,未在参数中指定为其指定模板的类型。 以下是此专业化的示例。
template<> std::string _min(std::string a, std::string b){ if(a.size() < b.size()){ return a; } return b; }
出于经济原因,将再次对特定类型的模板进行专门化:如果代码中未使用此版本的功能模板,则它将不会包含在二进制代码中。
将来,将保留多个和整数参数。 一个自然的扩展是类模板,生成式编程的基础以及C ++标准库的设计。 还有很多例子!