C++ - 非类型模版参数和模版的特化

目录

非类型模版参数

模版的特化

函数模版特化

类模版特化

全特化

半特化(偏特化)

参数更进一步的限制


非类型模版参数

在之前学过的例子来看,我们使用模版,它们的参数都是类型模版,根据类型来决定实例化

而模版其实还有一种参数,叫做 非类型模版参数

//非类型模版参数 --- 常量
template     
class array
{
private:
	T _arr[N];
};

int main()
{
	int a = 10;
	const int i = 10;
	fjz::array arr1;   //a是变量,编译会报错
	fjz::array arr2;   
	fjz::array arr3;
}

非类型模版参数,它是一个常量,所以如果要传参,也必须只能传一个常量,传变量会报错!!

模版的特化

C++支持了模版之后,给我们写代码带了了很大的便利,而模版的特化,更是近一步优化了模版的特点!

看这样一种场景

template
bool less(T v1, T v2)
{
	return v1 < v2;
}

int main()
{
    int i1 = 5;
	int i2 = 4;

	int* p1 = &i1;
	int* p2 = &i2;

	cout << fjz::less(i1, i2) << endl;
	cout << fjz::less(p1, p2) << endl;
	cout << endl;
}

如果我们不是想比较指针的大小,而是想比较指针解引用的数据的大小,那么遇上这种情况怎么办?  使用函数模版特化或者是类模版特化

函数模版特化

template
bool less(T v1, T v2)
{
	return v1 < v2;
}

//函数模版特化格式
template<>
bool less(int* v1, int* v2)
{
	return *v1 < *v2;
}

这时我们就可以对于int* 这一类型进行专门的特化,一旦是发现T类型是int*,就会使用特化版本!

类模版特化

类模板的特化相对于函数模版的特化,多了几种特化形式,适用于不同的场景,更加灵活!

全特化

类模版的全特化与函数模版特化一样

//原模版
template
class A {
public:
	void func(T1 t1, T2 t2)
	{
		std::cout << "class A" << std::endl;
	}
};

//全特化
template<>
class A {
public:
	void func(int t1,char t2)
	{
		std::cout << "class A" << std::endl;
	}
};

int main()
{
	A().func();
	A().func();

	return 0;
}

C++ - 非类型模版参数和模版的特化_第1张图片

对于模版参数类型的不同,遇到特化相匹配的类型,会优先匹配优化版本的模版类。

半特化(偏特化)

顾名思义,只特化模版参数的某些参数,一些参数不进行特化。

//原模版
template
class A {
public:
	void func()
	{
		std::cout << "class A" << std::endl;
	}
};

//全特化
template<>
class A {
public:
	void func()
	{
		std::cout << "class A" << std::endl;
	}
};

//半特化(偏特化)
template
class A {
public:
	void func()
	{
		std::cout << "class A" << std::endl;
	}
};

int main()
{
	A().func();
	A().func();
	A().func();

	return 0;
}

C++ - 非类型模版参数和模版的特化_第2张图片

 编译器会匹配 类型最为匹配的版本。

参数更进一步的限制

还有一种更为特别的特化,针对指针和引用

//原模版
template
class A {
public:
	void func()
	{
		std::cout << "class A" << std::endl;
	}
};

//还有一种特化方式,专门特化指针和引用
template
class A
{
public:
	void func()
	{
		std::cout << "class A" << std::endl;
	}
};

template
class A
{
public:
	void func()
	{
		std::cout << "class A" << std::endl;
	}
};

template
class A
{
public:
	void func()
	{
		std::cout << "class A" << std::endl;
	}
};

template
class A
{
public:
	void func()
	{
		std::cout << "class A" << std::endl;
	}
};

int main()
{
	A().func();
	A().func();
	A().func();
	A().func();
	A().func();
	A().func();
	A().func();

	return 0;
}

C++ - 非类型模版参数和模版的特化_第3张图片

  编译器会匹配 类型最为匹配的版本。

你可能感兴趣的:(C++初阶知识,c++,开发语言)