版权声明:转载请注明出处,谢谢!!! 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;
}
运行结果:
小结论:对于三种类模板的调用优先级从高到低为:全特化>偏特化>一般。