泛型是程序设计语言的一种特性。容许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须做出指明。ios
各类程序设计语言和其编译器、运行环境对泛型的支持均不同。将类型参数化以达到代码复用提升软件开发工做效率的一种数据类型。程序员
数据的值能够经过函数参数传递,在函数定义时数据的值是未知的,只有等到函数调用时接收了实参才能肯定其值。这就是值的参数化。ide
#include<iostream> using namespace std; //比较int类型大小 int myMax(int a, int b) { return a>b ? a : b; } //比较double类型大小 double myMax(double a, double b) { return a>b ? a : b; } int main() { //针对不一样类型求最大值 cout << myMax(10, 20) << endl; cout << myMax(1.22, 3.44) << endl; return 0; }
在C++中,数据的类型也能够经过参数来传递,在函数定义时能够不指明具体的数据类型,当发生函数调用时,编译器能够根据传入的实参自动推断数据类型。这就是类型的参数化。函数
template<typename T> T max(T a, T b) { return a > b ? a : b; }
max<int>(2, 3);
函数模板表明一个函数族,它所用到的数据的类型(包括返回值类型、形参类型、局部变量类型)能够不具体指定,而是用一个标识符来代替。函数调用时根据实参逆推出真正类型,生成具体函数的二进制代码。spa
template <typename 类型参数1, typename 类型参数2, ...> 返回值类型 函数名(形参列表) { //模板函数体 }
typename能够用class替换.此处class不是表示类,由于早期C++没有typename而是用class表示类型参数名字。设计
函数名<参数类型1,参数类型2>(形参表); 函数名(形参表);
编译器根据调用函数模板提供的模板实参,将所调用的函数模板编译成具体函数的过程,称为函数模板的实例化。指针
函数模板是二次编译。编译器第一次看到函数定义,检查语法,生成内部结构。第二次,将提供的具体类型实参结合以前内部结构生成具体函数二进制指令。ci
隐式推断的同时不能作隐式类型转换开发
#include<iostream> using namespace std; //函数模板 template<typename T> void fun(T const& a, T const& b) { cout << typeid(a).name() << " " << typeid(b).name() << endl; } template<typename T1, typename T2> void foo(T1 const& a, T2 const& b) { cout << typeid(T1).name() << " " << typeid(T2).name() << endl; } int main() { fun(10, 5); //fun(5, 10.0); //隐式推断的同时不能作隐式类型转换 foo(5, 10.0); //增长一种类型便可 cin.get(); return 0; }
重载优先选择普通版本字符串
#include<iostream> using namespace std; #include<string> //任意类型大小 template<typename T> T const& myMax(T const& a, T const& b) { cout << "<TT>" << flush << endl; return a>b ? a : b; } //任意指针类型大小 template<typename T> T* const& myMax(T* const& a, T* const& b) { cout << "<T* T*>" << flush << endl; return a>b ? a : b; } //C风格字符串的最大值 //const char* myMax(char const*a, char const*b) //加const&是为了防止拷贝构造 const char* const& myMax(char const* const& a, char const* const& b) { cout << "const char* const&" << endl; return strcmp(a, b)>0 ? a : b; } int main() { const char* a = "abc"; const char* b = "def"; const char* c = "xyz"; //重载优先选择普通版本,除非函数模板能提供更好更匹配的函数 myMax(a, b); //比较任意类型大小 myMax(10, 10); //选择普通版本 myMax((char*)a, b); //调用模板 myMax<>(a, b); myMax<const char*>(a, b); cin.get(); return 0; }
const char* const& <TT> const char* const& <T* T*> <TT>