模版函数
1.1 目前函数的问题
#include <iostream>
using namespace std;
/*
以下函数存在的问题
1. 功能一致,但是函数参数类型不同
2. 按照目前的技术手段,只能分别实现不同的函数完成代码
3. 导致代码冗余、函数冗余、编译冗余
解决方案:
利用 C++ 模版解决
*/
void printValue(int num);
void printValue(double num);
void printValue(char ch);
void printValue(bool ret);
void printValue(string s);
int main(int argc, char const *argv[])
{
printValue(10);
printValue(3.14);
printValue('G');
printValue(false);
printValue("零零零零");
return 0;
}
void printValue(int num) { cout << num << endl; }
void printValue(double num) { cout << num << endl; }
void printValue(char ch) { cout << ch << endl; }
void printValue(bool ret) { cout << ret << endl; }
void printValue(string s) { cout << s << endl; }
1.2 模版函数案例
#include <iostream>
#include <deque>
using namespace std;
/*
template 单词汉语对应就是模版
在这里自定义模版,设置模版数据类型为 T 类型
T 是一个数据类型占位符!且不具备实际含义
【模版函数】函数使用模版 T,需要再调用函数时明确 T 对应的具体函数数据类型
*/
template <typename T>
void printValue(T t);
int main(int argc, char const *argv[])
{
/*
void printValue<int>(int t)
实际参数时 int 类型,当前模版 T 对应的具体数据类型为
int 类型,编译器在编译过程中,动态的对当前模版函数进行了
修改操作来满足当前函数做需要。
*/
printValue(100);
// void printValue<double>(double t)
printValue(3.14);
// void printValue<float>(float t)
printValue(6.18F); // 自动变成 float 类型
// void printValue<char>(char t)
printValue('G');
// void printValue<bool>(bool t)
printValue(true);
// void printValue<const char *>(const char *t)
printValue("零零零零");
return 0;
}
template <typename T>
void printValue(T t)
{
cout << "Value : " << t << endl;
}
1.3 模版函数细节
#include <iostream>
using namespace std;
template <typename T>
void test(T t);
/*
模版声明没有任何的冲突问题,尤其是模版函数,相互独立
*/
template <typename T>
void test(T t1, T t2);
/*
当需要调用两个参数类型不同时,可以采用两个模版函数调用
*/
template <typename T, typename Y>
void test2(T s1, Y s2);
void test(int n);
int main(int argc, char const *argv[])
{
/*
当前代码中,针对于 test 函数没有具体参数数据类型为 double 情况
编译器会选择模版函数为当前执行的目标,并且在当前函数调用的过程中
明确模版对应的具体数据类型为 【double】 类型
*/
test(20.5F);
/*
test 函数存在重载情况,分别是对应模版函数和 int 具体数据类型函数
编译器会优先选择具体数据类型明确的函数,调用实现
【先实后虚】
*/
test(20);
/*
template <typename T>
void test(T t1, T t2)
语法错误!!!因为当前函数有且只声明了一个模版 T,
要求在函数的执行过程中,T 类型唯一且统一
test(10, 3,14); (int, double) 语法错误!
*/
test(10, 20);
// test(10, 'A'); 语法错误!请遵守【数据类型一致化原则】
test('A', 'B');
test2(10, 'A');
return 0;
}
template <typename T>
void test(T t)
{
cout << "模版函数触发 value : " << t << endl;
}
void test(int n)
{
cout << "具体参数为 int 类型函数触发 value : " << n << endl;
}
template <typename T>
void test(T t1, T t2)
{
cout << "Value 1 : " << t1 << ", Value 2 : " << t2 << endl;
}
template <typename T, typename Y>
void test2(T s1, Y s2)
{
cout << "Value 1 : " << s1 << ", Value 2 : " << s2 << endl;
}
#include <iostream>
using namespace std;
class Person
{
public:
Person() {}
Person(int id, string name, int age) : id(id), name(name), age(age) {}
Person(const Person &p) : id(p.id), name(p.name), age(age) {}
~Person() {}
friend ostream &operator<<(ostream &o, Person *p);
int id;
string name;
int age;
};
ostream &operator<<(ostream &o, Person *p)
{
o << "ID : " << p->id << ", Name : " << p->name
<< ", Age : " << p->age;
return o;
}
/*
函数中第一个参数 T1 t1 对应的是当前模版声明中的 T1
函数中第一个参数 T1 t2 对应的是当前模版声明中的 T2
都需要具体的实际参数类型来约束模版对应的具体数据类型
*/
template <typename T1, typename T2>
void test(T1 t1, T2 t2)
{
cout << "T1 : " << t1
<< " T2 : " << t2 << endl;
}
template <typename T>
void mySwap(T &t1, T &t2)
{
T temp = t1;
t1 = t2;
t2 = temp;
}
/*
template<> 告知编译器,当前函数需要使用模版函数形式
没有明确的模版类型声明
函数名之后加入的中括号和具体数据类型
mySwap<Person> 明确告知编译器,
当前模版对应的具体数据类型为 Person 类型
按照函数声明
template <typename T>
void mySwap(T &t1, T &t2);
T类型对应的具体数据类型在当前实现函数中为 Person 类型
定制化完成 Person 类型的 Swap 交换操作
*/
template <>
void mySwap<Person>(Person &t1, Person &t2)
{
int id = t1.id;
string name = t1.name;
int age = t1.age;
t1.id = t2.id;
t1.name = t2.name;
t1.age = t2.age;
t2.id = id;
t2.name = name;
t2.age = age;
}
int main(int argc, char const *argv[])
{
// 模版对应的类型需要根据实际情况下来进行判断
/*
void test<int, int>(int t1, int t2)
*/
test(10, 20);
/*
void test<int, char>(int t1, int t2)
*/
test(10, 'A');
int n1 = 10;
int n2 = 20;
mySwap(n1, n2);
cout << "n1 : " << n1 << " n2 : " << n2 << endl;
double d1 = 3.14;
double d2 = 6.18;
mySwap(d1, d2);
cout << "d1 : " << d1 << " d2 : " << d2 << endl;
cout << "-------------------------------" << endl;
Person *p1 = new Person(1, "张三", 3);
Person *p2 = new Person(2, "李四", 5);
cout << p1 << endl;
cout << p2 << endl;
cout << "-------------------------------" << endl;
mySwap(*p1, *p2);
cout << p1 << endl;
cout << p2 << endl;
return 0;
}
Person *p1 = new Person(1, "张三", 3);
Person *p2 = new Person(2, "李四", 5);
cout << p1 << endl;
cout << p2 << endl;
cout << "-------------------------------" << endl;
mySwap(*p1, *p2);
cout << p1 << endl;
cout << p2 << endl;
return 0;
}