【C++基础】模板基础与函数模板

128 阅读2分钟

目录

初识模板

求两个int、float、char类型的数据的最大值:
C里面要这样写:

int maxInt(int x, int y);
double maxDouble(double x, double y);
char maxChar(char x, char y);

C++使用函数重载(多个同名函数处理多种类型数据的语法现象)可以使得三个函数的名字一样:
在这里插入图片描述
而我们期待的是下面这种类型:
在这里插入图片描述

函数模板

单个类型参数:

template <typename T>
returnType function(T para1,...) {
	//Body
}

在函数模板中,可以用泛型的地方包括:
1、函数返回值
2、函数参数
3、函数局部变量

多个类型参数:

template <typename T, typename S>
auto add(T x1, S x2) {
	return (x1 + x2);
}

在主函数中调用此函数:

int main() {
	auto y = add(1,2.0);
	return 0;
}

编译器根据函数调用的实参,生成函数模板的实例:

在这里插入图片描述

函数模板实例化

注意模板多态属于静态联编,与函数重载属于同一层面。
有两种实例化方法 (确定模板实参的方法):

Explicit instantiation (显式实例化)
Implicit instantiation (隐式实例化)

显式实例化

强制某些函数实例化,可出现于程序中模板定义后的任何位置。

template < typename T >
void f( T s ){
  std::cout << s << '\n';
}
template void f<double>(double); // 实例化,编译器生成代码
                                //  void f(double s) {   // T: double
                               //      std::cout << s << '\n';
                               //  }
template void f<>(char);    // 实例化 f<char>(char) ,推导出模板实参
template void f(int);        // 实例化 f<int>(int) ,推导出模板实参

隐式实例化

编译器查看函数调用,推断模版实参,实现隐式实例化。

#include <iostream>
template<typename T>
void f(T s) {
    std::cout << s << '\n';
}
int main(){
    f<double>(1); // 实例化并调用 f<double>(double)
    f<>('a'); // 实例化并调用 f<char>(char)
    f(7); // 实例化并调用 f<int>(int)
    void (*ptr)(std::string) = f; // 实例化 f<string>(string)
}

由函数模板实例化得到的函数叫做“实例函数”,由类模板实例化得到的类叫做“实例类”