C++模板

一.定义

可以理解为通用模具,增强代码复用性,分为函数模板和类模板

二.特征

类型名称为class或typename

template
//或者
tempalte

注意:

在调用的时候才会实例化为具体的函数或类,如果在运行时未实例化,模板中的语法错误可能不会报错

1.函数模板

template
T add(T a, T b)
{
	return a + b;
}

2.类模板

可以修饰成员函数和成员变量

template
class test
{
public:
    T Add()
	{
		return _x+_y; 
	}
private:
	T _x;
	T _y;
}

当修饰成员函数,且成员函数在类外定义时

template
class test
{
public:
	T Add();
}
//在类外定义
template
T test::Add()
{
	return _x+_y;
} 

Add函数的定义需要再次定义一个模板,因为编译器不知道这个函数是否为带模板的函数,所以需要再次使用。

三.模板实例化

1.函数模板实例化

template
T add(T a, T b)
{
	return a + b;
}

(1)隐式实例化

编译器自动识别

int i = 1;
int j = 2;
add(i, j);

(2)类型强转

int i = 1;
double j = 2.2;
add(i, (int)j);

(3)显示实例化

int i = 1;
double j = 2.2;
add(i, j);

2.类模板实例化

template
class test
{
public:
    T Add()
	{
		return _x+_y; 
	}
private:
	T _x;
	T _y;
}
test ts;

四.非类型模板参数

即将常量作为类模板的参数

template
class test
{
private:
//一个存放N个T类型数据的成员
	T arr[N];
};


int main()
{
//传参,实例化
   test s;
   return 0;
}

注意:

浮点数,类对象,字符串不允许作为非类型模板参数

五.模板的特化

针对某些类型的特殊处理

1.全特化

特化的类和函数的参数不含未知量

函数

template
void func(T x,T y)
{
}

template<>
void func(char x, char y)
{
}

template
class M
{
};

template<>
class M
{
};

2.偏特化

特化的类和函数的参数含部分未知量

(定义特化部分时,哪部分未特化,传哪部分的参数)

(1)半特化

函数

template
void func(T1 x,T2 y)
{
}

template
void func(T1 x, int y)
{
}

template
class M
{
};

template
class M
{
};

(2)引用和指针

函数

template
void func(T x)
{
}

//引用
template
void func(T& x)
{
}

//指针
template
void func(T* x)
{
}

template
class M
{
};

//引用
template
class M
{
};

//指针
template
class M
{
};

六.模板的分离编译

模板不能声明和定义分开,因为头文件中函数或类模板声明被实例化时,cpp文件中函数或类模板定义未实例化,导致程序运行时链接找不到对应类型的函数或类

解决方法;

显示实例化(在模板定义的文件中)

函数

template
void func(T x)
{
}

template
void func(int x);

template
class M
{
};

template
class M;

缺点:

用一种类型必须要显示实例化一种

你可能感兴趣的:(c++,开发语言)