C++函数模板 C 语言中文网
在这个学期开始学习使用模板,当然模板早在大一期间就用到了一些,但是都是作为练习语法用的。这个学期中使用了大量的模板来进行类的设计与实现,具体的来说应该几乎是这个学期的所有的C++代码都是用的模板实现的吧。有些即使没那么大的使用模板价值,但是还是为了积累模板的经验而硬使用了模板。写了这么多的模板后,也就是在上个星期才偶尔在一个帖子里看到默认模板参数这个概念,写了那么多的代码了才知道这个概念感觉很羞愧啊,就去学习了学习。其实这个如果对照普通类型的默认变量来看待,其实也是不难理解的。
就像标题说的那样:模板类支持默认模板参数、模板函数不支持默认模板参数,这里的模板函数包括全局函数与类成员函数两种。
使用说明一:
- //模板类的默认模板参数
- template<class TypeA = int, class TypeB = float>
- class MyClass
- {
- public:
- TypeA value_A;
- TypeB value_B;
- public:
- MyClass(TypeA valA,TypeB valB)
- {
- value_A = valA;
- value_B = valB;
- }
- MyClass(){}
- ~MyClass(){}
- TypeA GetValueA()
- {
- return value_A;
- }
- TypeB GetValueB();
- //类成员函数模板
- template<typename T>
- void MemberFuntion(T Tval)
- {
- cout<<"成员函数模板的类型名: "<<typeid(T).name()<<endl;
- cout<<"模板成员函数的值: "<<Tval<<endl;
- }
- };
- //默认模板参数的类模板成员函数类外定义方式,在定义这里就不用再声明默认模板参数类型了
- template<class TypeA,class TypeB>
- TypeB MyClass<TypeA,TypeB>::GetValueB()
- {
- return value_B;
- }
主函数的调用:
- MyClass<> cls(1,2.0f); //因为已经是默认的模板参数了,所以可以不用在实例化类的时候声明类型,但是尖括号是必须要有的
- cout<<cls.GetValueA()<<endl;
- cls.MemberFuntion<float>(11.0f); //成员函数的模板声明方式
运行的结果是:
使用说明二:
对于主函数还可以这么调用:
- MyClass<char,char> clsch('z','l'); //这里主动声明了类模板的参数类型,覆盖了原有的默认模板参数类型
- cout<<"value_A的值: "<<clsch.GetValueA()<<endl;
- cout<<"value_B的值: "<<clsch.GetValueB()<<endl;
- clsch.MemberFuntion<>("hello"); //可以不声明成员函数的模板类型,因为可以根据传进去的参数类型进行匹配模板参数类型。但如果函数没有参数的话,又没有显示的声明类型,那么在静态编译阶段就不能确定模板参数类型,会抛错。
运行结果:
说明:"hello"的默认类型是常量指针(指向常量字符串的指针),因为一个字符串是被当做是一个常量对待的,存储于常量区。
使用说明三:
- //类成员函数模板
- template<typename T = int>
- void MemberFuntion(T Tval)
- {
- cout<<"成员函数模板的类型名: "<<typeid(T).name()<<endl;
- cout<<"模板成员函数的值: "<<Tval<<endl;
- }
如果在成员函数模板中默认模板参数,那么会抛错:error C4519: 仅允许在类模板上使用默认模板参数。
#include <iostream>
using namespace std;
//一样的模式吖,模板实例化的时候不是需要填参数么,这样做目的就是缺省一个啊
template <class TypeA = int , class TypeB = float>
class MyClass
{
public:
MyClass(TypeA a, TypeB b)
{
if(typeid(TypeA) == typeid(TypeB))
{
cout << typeid(TypeA).name();
}
value_A = a;
value_B = b;
}
virtual ~MyClass(){}
template < class T >
void memberFunc(T val)
{
cout << typeid(T).name() << endl;
// C++ 关键字 typeid, typename
cout << "模板成员函数的值 :" << val << endl;
}
template <class T>
void show( T a);
private:
TypeA value_A;
TypeB value_B;
};
template <class TypeA , class TypeB> //实现 不要 同事也不能生
template<class T>
inline void MyClass<TypeA, TypeB>::show( T a)
{
cout << a << '\n';
}
// ***********************************
template <class TypeC>
class MyClass_2 : public MyClass<> //MyClass<TypeA, TypeB>
{
public:
virtual ~MyClass_2<TypeC>() {} // zhe不是性偶函数
// MyClass_2(TypeC c, TypeA a, TypeB b);
MyClass_2(TypeC c);
template <class Type>
void show(Type a);
private:
TypeC name;
};
template<class TypeC>
//MyClass_2<T>::MyClass_2(int a, int b, int c):MyClass(b, c) 不对啊
//{
// name = a;
//}
MyClass_2<class TypeC>::MyClass_2(TypeC c)
{
name = c;
}
// lei 模版中的 模版函数
template <class T>
template <class Type>
void MyClass_2<T>::show(Type a)
{
}
int main(int argc, const char * argv[])
{
// 模板类的默认模板参数、模板函数不支持默认模板参数
MyClass<> obj(1, 2.0); //?
obj.memberFunc<float>(11); //?
obj.show<int>(10);
return 0;
}