c++模板、模板的全特化与偏特化

版权声明:转载请注明出处,谢谢!!! https://blog.csdn.net/qhdhnbd110/article/details/83651232

1. c++模板的一般使用方法

 1. 类模板

#include<iostream>
using namespace std;
template <typename T>
class MyClass
{
public:
	MyClass <T>(T a, T b)
	{
		this->a = a;
		this->b = b;
	}
public:
	T GetA()
	{
		return this->a;
	}
	T GetB()
	{
		return this->b;
	}
private:
	T a;
	T b;
};
int main()
{
	//MyClass mc; //错误,必须指定类型,因为要开辟空间
	MyClass<int> mc(3, 4);
	cout << "mc.a:" << mc.GetA() << '\n' << "mc.b:" << mc.GetB() << endl;
    return 0;
}

输出结果:

我们再尝试将成员函数在类外定义:

template <typename T>
class MyClass
{
public:
	MyClass <T>(T a, T b)
	{
		this->a = a;
		this->b = b;
	}
public:
	T GetA();
	T GetB();
private:
	T a;
	T b;
};
T MyClass::GetA()
{
	return this->a;
}
T MyClass::GetB()
{
	return this->b;
}

 如果以这种常规形式类外定义类成员,我们发现是无法通过编译的:

第一个问题:T编译器不认识了;

第二个问题:缺少类模板MyClass的参数列表

为了让编译器再次认识T,我们将template <typename T>拿到每个函数上面;然后在MyClass后面加上模板参数列表:

template <typename T>
T MyClass<T>::GetA()
{
	return this->a;
}
template <typename T>
T MyClass<T>::GetB()
{
	return this->b;
}

这样程序就可以正常的运行了。

小结论:在类外定义模板类成员函数时,格式为:template<T> 返回值   类名<T>:: 函数名(){} ;

另外,在所有出现MyClass的地方都需要模板参数列表。

2. 函数模板

#include<iostream>
using namespace std;
template <typename T>
T Add(T a, T b)
{
	return a + b;
}
int main()
{
	cout << Add(1, 2) << endl;
    return 0;
}

可以看到:调用Add时并没有在Add后添加模板参数列表。

运行结果:

小结论:类模板不能自动推演模板的类型,而函数模板可以根据参数自动匹配。

 2. c++类模板的全特化

#include<iostream>
using namespace std;
template <typename T1, typename T2>
class MyClass
{
public:
	MyClass <T1, T2>(T1 a, T2 b)
	{
		this->a = a;
		this->b = b;
	}
public:
	T1 GetA(){return this->a;}
	T2 GetB(){return this->b;}
private:
	T1 a;
	T2 b;
};
//实现了MyClass的全特化
template <>
class MyClass<int, char>
{
public:
	MyClass (int a, char b)
	{
		this->a = a;
		this->b = b;
	}
public:
	int GetA(){return this->a;}
	char GetB(){return this->b;}
private:
	int a;
	char b;
};
int main()
{
	//MyClass mc; //错误,必须指定类型,因为要开辟空间
	MyClass<int, char> mc(3, 'c');
	cout << "mc.a:" << mc.GetA() << '\n' << "mc.b:" << mc.GetB() << endl;
    return 0;
}

运行结果:

显而易见,全特化的意思就是将原本模板的泛型参数全部变成了指定的类型。

 3. c++类模板的偏特化

 理解了全特化,偏特化就不难理解了:

template <typename T1, typename T2>
class MyClass
{
public:
	MyClass <T1, T2>(T1 a, T2 b)
	{
		this->a = a;
		this->b = b;
	}
public:
	T1 GetA(){return this->a;}
	T2 GetB(){return this->b;}
private:
	T1 a;
	T2 b;
};
template <typename T2>
class MyClass<int, T2>
{
public:
	MyClass (int a, T2 b)
	{
		this->a = a;
		this->b = b;
	}
public:
	int GetA(){return this->a;}
	T2 GetB(){return this->b;}
private:
	int a;
	T2 b;
};

可以看出,偏特化就是原本模板的泛型参数部分变成了指定的类型。

4. 三种类模板类型的调用优先级

#include<iostream>
using namespace std;
template <typename T1, typename T2>
class MyClass
{
public:
	MyClass(){}
public:
	void WhoAmI()
	{
		cout << "I am general one" << endl;
	}
};
template <>
class MyClass<int, char>
{
public:
	MyClass(){}
public:
	void WhoAmI()
	{
		cout << "I am complete one" << endl;
	}
};
template <typename T2>
class MyClass<int, T2>
{
public:
	MyClass(){}
public:
	void WhoAmI()
	{
		cout << "I am incomplete one" << endl;
	}
};
int main()
{
	MyClass<int, char> mc1;
	mc1.WhoAmI();
	MyClass<int, double> mc2;
	mc2.WhoAmI();
	MyClass<char, double> mc3;
	mc3.WhoAmI();
    return 0;
}

运行结果:

小结论:对于三种类模板的调用优先级从高到低为:全特化>偏特化>一般。

猜你喜欢

转载自blog.csdn.net/qhdhnbd110/article/details/83651232