一文带你掌握C++模版

Rockivy- 2024-08-02 16:31:09 阅读 72

12. C++模板

什么是模板

模板编程也可以叫做泛型编程,忽略数据类型的一种编程方式

<code>//求最值问题

int Max(int a,int b)

{

return a>b?a:b;

}

double Max(int a,int b)

{

return a>b?a:b;

}

string Max(string a,string b)

{

return a>b?a:b;

}

//引入模板编程

template <typename type> //告诉编译器,下面会用到一个未知类型叫做type

type Max(type a,type b)

{

return a>b?a:b;

}

模板代码

#include <iostream>

using namespace std;

template <typename type>

type Max(type a, type b)

{

return a > b ? a : b;

}

//typename 可以用class 替换

template <class T>

void print(T data)

{

cout << data << endl;

}

int main()

{

//隐式调用

cout << Max(1, 2) << endl;

cout << Max(1.1, 2.2) << endl;

//string 和char* 有区别

cout << Max(string("1ILoveyou"), string("2IMissyou")) << endl;

//显示调用 <>传类型的参数

cout << Max<int>(1, 2) << endl;//type=int a=1 b=2

cout << Max<string>(string("1"), string("2")) << endl;

cout << Max<double>(1.2, 1.3) << endl;

return 0;

}

函数模板

函数模板重载问题

函数模板和普通函数

函数模板和函数模板

<code>#include <iostream>

using namespace std;

//No.1 模板与普通函数

int Max(int a, int b)

{

cout << "普通函数..." << endl;

return a > b ? a : b;

}

template <class T>

T Max(T a, T b)

{

cout << "模板" << endl;

return a > b ? a : b;

}

//No.2 模板与模板

template <class type1,class type2,class type3>

void print(type1 one, type2 two, type3 three)

{

cout << "三只" << endl;

}

template <class type1,class type2>//type1=int type2=double

void print(type1 one, type1 two, type2 tow) //int int double

{

cout << "两只" << endl;

}

template <class type>

void print(type one, type two, type three)

{

cout << "一只" << endl;

}

int main()

{

cout << Max<int>(1, 2) << endl;//显式调用,百分百调用模板

cout << Max(1, 2) << endl;//优先调用类型确定的函数

cout << "显示调用" << endl;

print<int, double, string>(1, 1.1, string("23"));

print<int, double>(1, 1, 1.22);

print<int>(1, 2, 3);

cout << "隐式调用" << endl;

print(1, 1, 2);//需要传参越少先调用

print(1, 1, string("sdsd"));

print(1, 1.11, string("sdsd"));//只有一种选择

return 0;

}

类成员函数是函数模板

//这种不叫做模板类型

class MM

{

public:

template <class T>

void print(T data)

{

cout << data << endl;

}

protected:

};

int main()

{

MM mm;

mm.print(1);

mm.print<string>("string");

return 0;

}

函数模板缺省

函数模板缺省和函数参数的缺省是一样的规则

//函数模板缺省

template <class type1,class type2=string>

void printData(type1 one, type2 two)

{

cout << one << endl;

cout << two << endl;

}

int main()

{

printData<int, double>(1, 1.22);

printData<int>(1, string("dsfsdf"));

return 0;

}

函数模板传常量

//函数模板传常量

template <class T,size_t size>

void printArray(T* array)

{

for (int i = 0; i < size; i++)

{

cout << array[i] << " ";

}

cout << endl;

}

int main()

{

int num[3] = { 1,2,3 };

printArray<int, 3>(num);

//下面代码报错

//int length = 3;

//printArray<int, length>(num);

string str[4] = { "sdds","sd","sdsd" ,"sdds"};

printArray<string, 4>(str);

return 0;

}

类模板

类模板的基础

怎么写类模板

类模板不是一个完整类型,所以任何用到类名的地方都需要用类名<未知类型>的方式使用

怎么去使用类模板,类模板必须采用显式调用方式

类模板在多文件中不能分开写

可以写在.hpp文件中(声明和实现都在一起)

#include <iostream>

#include <map>

using namespace std;

template <class type1,class type2>

struct my_pair

{

type1 first;//键

type2 second;//值

my_pair(type1 first, type2 second) :first(first), second(second) { }

my_pair() = default;

};

template <class type1,class type2>

my_pair<type1, type2> my_make_pair(type1 one, type2 two)

{

return my_pair<type1, type2>(one, two);

}

template <class type1,class type2>

class Test

{

public:

Test(type1 one, type2 two) :one(one), two(two)

{

}

void printTest();

protected:

type1 one;

type2 two;

};

template <class type1, class type2>

void Test<type1,type2>::printTest()

{

cout << one << " " << two << endl;

}

template <class type1,class type2>

class Data :public Test<type1,type2>

{

public:

Data(type1 one, type2 two) :Test<type1, type2>(one, two)

{

}

protected:

};

int main()

{

my_pair<int,int> pairData = { 1,2 };

cout << pairData.first << " " << pairData.second << endl;

my_pair<int, string>* p = new my_pair<int, string>;

p->first = 12;

p->second = "sdsd";

cout << p->first << " " << p->second << endl;

Data<int, int> data(1, 2);

data.printTest();

//标准库中的pair类型

pair<int, string> pD(1, "ILoveyou");

cout << pD.first << " " << pD.second << endl;

pair<int, string> testData = make_pair<int, string>(1, "sdfsdf");

my_pair<int, string> my_testData =my_make_pair<int, string>(1, "sdfsdf");

return 0;

}

类模板特化问题

局部特化完全特化

特化的目的是为了适应不同数据的不同处理

#include <iostream>

using namespace std;

template <class _Ty1,class _Ty2,class _Ty3>

class Data

{

public:

Data(_Ty1 one, _Ty2 two, _Ty3 three) :one(one), two(two), three(three) { }

void printData()

{

cout << (one + two + three) << endl;

}

private:

_Ty1 one;

_Ty2 two;

_Ty3 three;

};

//局部特化

//两个数据,打印两数之差

template <class _Ty1,class _Ty2>

class Data<_Ty1,_Ty1,_Ty2>

{

public:

Data(_Ty1 one, _Ty2 two) :one(one), two(two){ }

void printData()

{

cout << (one -two) << endl;

}

private:

_Ty1 one;

_Ty2 two;

};

//只有一个数据,打印数据

template <class _Ty1>

class Data<_Ty1,_Ty1,_Ty1>

{

public:

Data(_Ty1 one) :one(one){ }

void printData()

{

cout << one << endl;

}

private:

_Ty1 one;

};

//完全特化

template <>

class Data<string, string, string>

{

public:

Data(string one,string two,string three):one(one),two(two),three(three)

{

}

void printData();

private:

string one;

string two;

string three;

};

void Data<string,string,string>::printData()

{

cout << one << " " << two << " " << three << endl;

}

int main()

{

Data<int, int, int> data1(1);

data1.printData();

Data<int,int, double> data2(2, 1);

data2.printData();

Data<int, double, float> data3(1, 1.1, 1.2f);

data3.printData();

Data<string, string, string> data4("dsd","sdfd","sdfdsf");

data4.printData();

return 0;

}

模板操作自定义类型

模板操作自定义关键点在于重载

#include <iostream>

#include <algorithm>

using namespace std;

class MM

{

public:

MM() = default;

MM(string name, int age) :name(name), age(age) { }

friend ostream& operator<<(ostream& out, const MM& object)

{

out << object.name << " " << object.age;

return out;

}

private:

string name;

int age;

};

template <class _Ty>

void printData(_Ty data)

{

cout << data << endl;

}

template <class _Ty1,class _Ty2,class _Ty3>

class Data

{

public:

//_Ty1=MM, _Ty2=int, _Ty3=int

Data(_Ty1 one, _Ty2 two, _Ty3 three) :one(one), two(two), three(three)

{

}

void printData()

{

cout << one << " " << two << " " << three << endl;

}

private:

_Ty1 one;

_Ty2 two;

_Ty3 three;

};

int main()

{

printData(1);

printData("string");

MM mm = { "小芳",18 };

printData(mm);

Data<MM, int, int> data(MM("小芳",18),98,99);

data.printData();

Data<MM, MM, MM> mmData(MM("小芳", 18), MM("小芳", 18), MM("小芳", 18));

mmData.printData();

return 0;

}

模板嵌套模板

关键点在于大家自己要清楚类型如何表示(类型是由类名<类型>表示一个类型)

#include <iostream>

using namespace std;

template <class _Ty1,class _Ty2,class _Ty3>

class Data

{

public:

Data(_Ty1 one, _Ty2 two, _Ty3 three) :one(one), two(two), three(three) { }

void printData()

{

cout << one << " " << two << " " << three << endl;

}

friend ostream& operator<<(ostream& out, Data<_Ty1, _Ty2, _Ty3>& object)

{

out << object.one << " " << object.two << " " << object.three;

return out;

}

protected:

_Ty1 one;

_Ty2 two;

_Ty3 three;

};

template <class _Ty1, class _Ty2>

class Info

{

public:

Info(_Ty1 one, _Ty2 two) :one(one), two(two) { }

void printData()

{

cout << one << " " << two << endl;

}

//template <class _Ty1, class _Ty2> 类中实现不需要修饰了,会出现重定义问题

friend ostream& operator<<(ostream& out, Info<_Ty1, _Ty2>& object)

{

out << object.one << " " << object.two << " ";

return out;

}

protected:

_Ty1 one;

_Ty2 two;

};

template <class _Ty1>

class Student

{

public:

Student(_Ty1 one) :one(one) { }

void printData()

{

cout << one << endl;

}

protected:

_Ty1 one;

};

int main()

{

Data<int, int, int> data(1,1,1); //Data<int, int, int>

Info<int, int> info(1, 2); //Info<int, int>

Info<Data<int, int, int>, Data<string, string, string>>

test1(Data<int, int, int>(1, 1, 1), Data<string, string, string>("ds", "sd", "sds"));

//起别名

using type1 = Data<int, int, int>;

using type2 = Data<string, string, string>;

//别名版本

Info<type1, type2>test2(type1(1, 1, 1), type2("ds", "sd", "sds"));

Data<Info<int, string>, Info<string, string>, Info<int, double>>

test3(Info<int, string>(1,"sd"), Info<string, string>("sdds","dsds"),Info<int, double>(1,1.11));

test1.printData();

test2.printData();

test3.printData();

Student<Data<Info<int, int>, Info<int, string>, Info<string, string>>>

stu(Data<Info<int, int>, Info<int, string>, Info<string, string>>

(Info<int, int>(1,1), Info<int, string>(1,"sdsd"), Info<string, string>("sds","sdsd")));

stu.printData();

return 0;

}



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。