C++模板编程

目录

一,模板函数

1,模板函数

2,多类型参数的模板函数

3,默认类型

4,模板间重载

5,模板函数的类型推导

二,模板类

1,模板类

2,多类型参数的模板类

3,默认类型

4,非类型参数

5,可继承性

6,友元

7,静态成员


一,模板函数

1,模板函数

像max这种函数,对于参数类型,计算逻辑是一样的,只是入参和返回值类型不同,就可以写成模板函数。

示例:

#include
using namespace std;

template
T maxmax(T a, T b)
{
	return (a > b ? a : b) + 1;
}

int main()
{
	cout << maxmax(1, 2) << endl;
	cout << maxmax(1.3, 1.5) << endl;
	cout << maxmax("as", "zx");
	return 0;
}

输出:

3
2.5
s

但是,不能这么调用:maxmax(1.3,1),这样写会报错,有重载歧义

2,多类型参数的模板函数

要实现有不同数据类型的入参的函数,就需要多个模板参数。

示例:

#include
using namespace std;

template
T1 maxmax(T1 a, T2 b)
{
	return (a > b ? a : b) + 1;
}

int main()
{
	cout << maxmax(1, 2) << endl;
	cout << maxmax(1.3, 1.5) << endl;
	cout << maxmax(1.3, 1) << endl;
	cout << maxmax("as", "zx");
	return 0;
}

输出:

3
2.5
2.3
s

3,默认类型

template
void f(T1 a)
{
	cout << a;
}

int main()
{
	int a = 1;
	f(a);
	f(1.5);
    return 0;
}

这个例子太简单了,看起来提供默认类型并没有什么用。

4,模板间重载

template
void f(T1 a)
{
	cout << 111;
}
template
void f(T1 a, T2 b)
{
	cout << 222;
}
template
void f(T1 a, T2 b, int c)
{
	cout << 333;
}
template
void f(T1 a, T2 b, double c)
{
	cout << 4444;
}

int main()
{
	int a = 1, b = 2;
	f(a);
	f(a, b);
	f(a, b, 1);
	f(a, b, 1.5);
	return 0;
}

输出:1112223334444

5,模板函数的类型推导

 我在用泛型编程写二维vector的排序模板时,写出这样一个代码:

//vector的字典序比较,v1=v2是false
template
bool cmp(vector&v1,vector&v2)
{
    for(int i=0;i
void sortVector(vector>&v)
{
    sort(v.begin(),v.end(),cmp);
}

编译结果:

1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(3802) : 参见“std::sort”的声明
1>c:\users\z00454773\documents\visual studio 2010\projects\20191228.cpp\20191228.cpp\csimsgeek.cpp(273): error C2780: “void std::sort(_RanIt,_RanIt)”: 应输入 2 个参数,却提供了 3 个

这就很奇怪了,一般在sort里面用自定义排序函数,就是加函数指针啊!

很快,我就想到了,这里的cmp是模板函数,它是需要根据类型参数来实例化的。

也就是说,模板函数直接调用是可以自动推导类型的,但是如果要用做函数指针的话,需要传入类型参数才能实例化

正确代码:

//vector的字典序排序
template
void sortVector(vector>&v)
{
    sort(v.begin(),v.end(),cmp);
}

二,模板类

1,模板类

和模板函数语法差不多。

示例:

#include
using namespace std;

template
class GetMax
{
public:
	T a;
	T b;
	GetMax(T a, T b)
	{
		this->a, this->b = b;
	}
	T getMax()
	{
		return a > b ? a : b;
	}
};

int main()
{
	int a = 1;
	cout << GetMax(a, 2.3).getMax();
	return 0;
}

有个很重要的区别就是,模板类在调用的时候必须显示的指明类型参数,

所以这里就像普通函数一样,会隐式地把int类型的数转换为double的数。

2,多类型参数的模板类

示例:

#include
using namespace std;

template
class GetMax
{
public:
	T1 a;
	T2 b;
	GetMax(T1 a, T2 b)
	{
		this->a, this->b = b;
	}
	T1 getMax()
	{
		return a > b ? a : b;
	}
};

int main()
{
	int a = 1;
	cout << GetMax(a, 3.3).getMax() << endl;
	cout << GetMax(a, 3.3).getMax();
	return 0;
}

输出:

3
3
 

3,默认类型

模板类定义时,类型参数也可以指定默认类型。

4,非类型参数

在定义模板类时,参数列表除了类型参数还可以有变量参数。

示例:

#include
using namespace std;

template
class Num
{
public:
	Num(T a)
	{
		this->num[0] = a;
	}
	T get()
	{
		return num[0];
	}
private:
	T num[len];
};

int main()
{
	cout << Num(2.3).get();
	return 0;
}

输出:

2

注意,创建模板类实例时,变量参数只能传常量,不能传变量,即使模板类中没有使用这个参数也是这样。

5,可继承性

模板类可以继承模板类,模板类可以继承非模板类,

非模板类可以继承模板类,非模板类可以继承非模板类。

6,友元

友元的使用,对于模板类和非模板类是一样的。

7,静态成员

对于模板类中的静态成员,每个模板特例化都拥有独立的静态数据域拷贝。

你可能感兴趣的:(c++)