本文是本人大一期间在校学习C++课程时所撰写的实验报告的摘录,由于刚上大学,刚接触计算机编程方面的相关知识,故可能会有很多不足甚至错误的地方,还请各位看官指出及纠正。
本文所涉及到的“教材”指:
电子工业出版社《C++ Primary中文版(第5版)》
如需转载或引用请标明出处。
基本知识
函数模板
当我们希望一个函数可以对多种不同的类型都执行相类似的操作时,我们可以通过定义一个通用的函数模板,而不是为每个类型都定义一个新的函数。一个函数模板就是一个公式,可以用来生成特定类型的函数版本。如:
template <typename T> int compare(const T& v1, const T& v2)
{
if (v1 < v2) return -1;
if (v2 < v1) return 1;
return 0;
}
模板定义以关键字template开始,后面跟一个用尖括号包围起来的模板参数列表,里面是用逗号分隔的一个或多个模板参数。模板参数列表的作用类似于函数参数列表,模板参数表示在类或函数定义中用得到的类型或值。当使用模板时,我们指定模板实参,将其绑定到模板参数上。
如上面的compare函数,使用一个名为T的模板参数,接受两个T类型(可以为int、float或double等)的常量引用作为实参,返回一个int。其作用为比较两个T,根据结果返回-1、1或0。
实例化函数模板
当我们调用一个函数模板时,编译器(通常)用函数实参来为我们推断模板实参。例如,在下面的调用中:
int a = compare(1, 0);
实参类型int,编译器会把它绑定到模板参数T上。
编译器用推断出的模板参数来为我们实例化一个特定版本的函数。当编译器实例化一个模板时,它使用实际的模板实参代替对应的模板参数来创建出模板的一个新“实例”。例如:
int a = compare(1, 0);
vector<int> vec1{ 1,2,3 }, vec2{ 4,5,6 };
int b = compare(vec1, vec2);
编译器会实例化出两个不同版本的compare。对于第一个调用,T被替换为int;对于第二个调用,T被替换为vector。
需要注意的是,替换T的类型必须满足函数中定义的操作条件。
关于示例程序
该程序定义了一个名为find的函数模板,它接受两个某种类型容器的迭代器和一个该容器中元素的类型作为实参,用于在某个容器中查找我们指定的元素。当以不同的形式调用find函数模板时,编译器自动实例化出不同的函数,以进行同一个查找操作。返回对应类型的迭代器。更多细节详见代码注释部分。
示例
源代码
main.cpp
#include <iostream>
#include <string>
#include <vector>
#include <list>
using namespace std;
//定义模板函数find,I是某种类型容器的迭代器类型,T是要在该容器中查找的元素类型
//名字定义为my_find是因为,find似乎会和原有的find函数冲突
//接受两个I类型的参数begin、end以及一个T类型的参数elem
template <typename I, typename T> I my_find(I begin, I end, const T& elem)
{
//遍历begin到end范围内的所有元素,直到超出范围或找到元素
while (begin != end && *begin != elem)
begin++;
return begin; //返回迭代器
}
int main(void)
{
//初始化两个不同类型的容器
vector<int> vi = { 1,3,5,7,9 };
list<string> ls = { "Hyper", "Energy", "Burst", "!" };
//用my_find在vector中查找
int elem1;
cout << "输入要查找的整数:";
cin >> elem1;
auto iter1 = my_find(vi.begin(), vi.end(), elem1); //iter1是一个存储int的vector的迭代器
//输出结果
if (iter1 == vi.end())
cout << "找不到该元素!" << endl;
else
cout << "该元素在此位置:" << iter1 - vi.begin() + 1 << endl;
//用my_find在list中查找
string elem2;
cout << "输入要查找的字符串:";
cin >> elem2;
auto iter2 = my_find(ls.begin(), ls.end(), elem2); //iter2是一个存储string的vector的迭代器
//输出结果
if (iter2 == ls.end())
cout << "找不到该元素!" << endl;
else
cout << "找到了该元素。" << endl;
system("pause");
return 0;
}
运行结果
依次输入7、Hyper,显示:
依次输入6、Hello,显示: