C++模板(二)

四、类模板的默认模板类型形参


1、可以为类模板的类型形参提供默认值,但不能为函数模板的类型形参提供默认值。函数模板和类模板都可以为模板的非类型形参提供默认值。

2、类模板的类型形参默认值形式为:template<class T1, class T2=int> class A{};为第二个模板类型形参T2提供int型的默认值。

3、类模板类型形参默认值和函数的默认参数一样,如果有多个类型形参则从第一个形参设定了默认值之后的所有模板形参都要设定默认值,比如template<class T1=int, classT2>class A{};就是错误的,因为T1给出了默认值,而T2没有设定。

4、在类模板的外部定义类中的成员时template 后的形参表应省略默认的形参类型。比如template<class  T1, classT2=int> class A{public: void h();};定义方法为template<classT1,class T2> void A<T1,T2>::h(){}


定义类模板类型形参:

演示实例1:

TemplateDemo.h

1 #ifndef TEMPLATE_DEMO_HXX

 2 #define TEMPLATE_DEMO_HXX
 3 
 4 template<class T> class A{
 5     public:
 6         T g(T a,T b);
 7         A();
 8 };
 9 

10 #endif


TemplateDemo.cpp

 1 #include<iostream.h>

 2 #include "TemplateDemo.h"

 3 

4 template<class T> A<T>::A(){}
 5 
 6 template<class T> T A<T>::g(T a,T b){
 7     return a+b;
 8 }
 9 
10 void main(){
11     A<int> a;
12     cout<<a.g(2,3)<<endl;
13 }


运行结果:       5


类模板的默认模板类型形参示例1

TemplateDemo03.h

1 #ifndef TEMPLATE_DEMO_03

 2 #define TEMPLATE_DEMO_03
 3 //定义带默认类型形参的类模板。这里把T2默认设置为int型。
 4 template<class T1,class T2=int> class CeilDemo{
 5     public:
 6         int ceil(T1,T2);
 7 };
 8 //在类模板的外部定义类中的成员时template 后的形参表应省略默认的形参类型。
 9 template<class T1,class T2> 
10 int CeilDemo<T1,T2>::ceil(T1 a,T2 b){
11     return a>>b;
12 }
13 

14 #endif


TemplateDemo03.cpp

1 #include<iostream.h>

2 #include "TemplateDemo03.h"

4 void main(){
5     CeilDemo<int> cd;
6     cout<<cd.ceil(8,2)<<endl;

7 }


运行结果:2


在类模板的外部定义类中的成员时template 后的形参表应省略默认的形参类型,如果没有省略,不会出现编译错误而是提出警告:

1 --------------------Configuration: TemplateDemo03 - Win32 Debug--------------------

2 Compiling...

3 TemplateDemo03.cpp
4 g:\c++\cdaima\templatedemo03\templatedemo03.h(12) : 
5 warning C4519: default template arguments are only allowed on a class template; ignored

7 TemplateDemo03.obj - 0 error(s), 1 warning(s)


原作者:类模板类型形参默认值和函数的默认参数一样,如果有多个类型形参则从第一个形参设定了默认值之后的所有模板形参都要设定默认值,比如template<class T1=int, classT2>class A{};就是错误的,因为T1给出了默认值,而T2没有设定。


实例测试如下:

类模板的默认模板类型形参示例2

 TemplateDemo03.h 

1 #ifndef TEMPLATE_DEMO_03

 2 #define TEMPLATE_DEMO_03
 3 
 4 template<class T1=int,class T2,class T3> class CeilDemo{
 5     public:
 6         int ceil(T1,T2,T3);
 7 };
 8 
 9 template<class T1,class T2,class T3> 
10 int CeilDemo<T1,T2,T3>::ceil(T1 a,T2 b,T3 c){
11     return a+b+c;
12 }
13 

14 #endif


TemplateDemo03.cpp 

1 #include<iostream.h>

2 #include "TemplateDemo03.h"

4 void main(){
5     CeilDemo<int,int> cd;
6     cout<<cd.ceil(2,3,4)<<endl;

7 }


运行结果:9

上例中我们看到,虽然多个类型形参则从第一个形参T1设定了默认值为int类型,但后面的两个并没有设定默认值。我们在声明对象的时候指明了T2T3的类型都为int类型,编译、运行没有任何警告和错误。但并不能否定原作者是错的,这只是一个特例,看下面的示例:


类模板的默认模板类型形参示例3

TemplateDemo03.h

 1 #ifndef TEMPLATE_DEMO_03

 2 #define TEMPLATE_DEMO_03
 3 
 4 template<class T1=int,class T2,class T3> class CeilDemo{
 5     public:
 6         double ceil(T1,T2,T3);
 7 };
 8 
 9 template<class T1,class T2,class T3> 
10 double CeilDemo<T1,T2,T3>::ceil(T1 a,T2 b,T3 c){
11     return a+b+c;
12 }
13 

14 #endif


TemplateDemo03.cpp

1 #include<iostream.h>

2 #include "TemplateDemo03.h"

4 void main(){
5     CeilDemo<double,double> cd;
6     cout<<cd.ceil(2,3.1,4.1)<<endl;

7 }


编译错误:

1 --------------------Configuration: TemplateDemo03 - Win32 Debug--------------------

 2 Compiling... 3 TemplateDemo03.cpp 4 g:\c++\cdaima\templatedemo03\templatedemo03.h(12) :  5 error C2244: 'CeilDemo<T1,T2,T3>::ceil' : unable to resolve function overload 6 g:\c++\cdaima\templatedemo03\templatedemo03.cpp(6) :  7 error C2065: 'cd' : undeclared identifier 8 g:\c++\cdaima\templatedemo03\templatedemo03.cpp(6) :  9 error C2228: left of '.ceil' must have class/struct/union type10 Error executing cl.exe.11 12 TemplateDemo03.obj - 3 error(s), 0 warning(s)


从上面的例子我们可以看出,当我们试图把T2T3定义为double类型就会出现错误(T1默认定义的是int类型)。那是不是我们按照作者所说把T2T3也设定为默认值double,是否还会出现错误?看下面的示例:


类模板的默认模板类型形参示例4

TemplateDemo03.h


1 #ifndef TEMPLATE_DEMO_03

 2 #define TEMPLATE_DEMO_03
 3 
 4 template<class T1=int,class T2=double,class T3=double> class CeilDemo{
 5     public:
 6         double ceil(T1,T2,T3);
 7 };
 8 
 9 template<class T1,class T2,class T3> 
10 double CeilDemo<T1,T2,T3>::ceil(T1 a,T2 b,T3 c){
11     return a+b+c;
12 }
13 

14 #endif


TemplateDemo03.cpp

1 #include<iostream.h>

2 #include "TemplateDemo03.h"

4 void main(){
5     CeilDemo<int,double,double> cd;
6     cout<<cd.ceil(2,3.1,4.1)<<endl;

7 }


编译错误:

 

--------------------Configuration: TemplateDemo03 - Win32 Debug--------------------

Compiling...
TemplateDemo03.cpp
g:\c++\cdaima\templatedemo03\templatedemo03.h(12) : 
error C2244: 'CeilDemo<T1,T2,T3>::ceil' : unable to resolve function overload
g:\c++\cdaima\templatedemo03\templatedemo03.cpp(6) : 
error C2065: 'cd' : undeclared identifier
g:\c++\cdaima\templatedemo03\templatedemo03.cpp(6) : 
error C2228: left of '.ceil' must have class/struct/union type
Error executing cl.exe.
 
TemplateDemo03.obj - 3 error(s), 0 warning(s)

从结果我们可以看出,和上例是一样的错误。从实例中我们可以总结如下:类模板如果有多个类型形参,如果使用类型形参默认值则尽量放在参数列表的末尾,而且默认的参数类型必须相同。如果从第一个形参设定了默认值之后的所有模板形参都要设定和第一个形参同类型的默认值。(声明:本人也是刚接触C++,以上只是我经过实例演示对原作者提出的一些质疑,可能我的示例有不到之处,还望大神们不吝赐教,共同完善此博客,给像我一样的菜鸟提供一个学习的平台!)

 

接下来验证不能为函数模板的类型形参提供默认值

 

类模板的默认模板类型形参示例5

 TemplateDemo04.cpp

1 #include<iostream.h>

 2  3 template<class T1,class T2,class T3> 4 T1 sum(T1 a,T2 b,T3 c=int){ 5     return a+b+c; 6 }  7  8 void main(){ 9     cout<<sum<double,double>(1.1,2.1,3)<<endl;10 }


编译错误:

1 --------------------Configuration: TemplateDemo04 - Win32 Debug--------------------

2 Compiling...
3 TemplateDemo04.cpp
4 g:\c++\cdaima\templatedemo04\templatedemo04.cpp(4) : 
5 error C2062: type 'int' unexpected
6 Error executing cl.exe.

8 TemplateDemo04.obj - 1 error(s), 0 warning(s)


更改之后的TemplateDemo.cpp

 1 #include<iostream.h>

 2  3 template<class T1,class T2,class T3> 4 T1 sum(T1 a,T2 b,T3 c){ 5     return a+b+c; 6 }  7  8 void main(){ 9     cout<<sum<double,short,int>(1.1,3,257)<<endl;10 }


运行结果:261.1


文章来源

http://www.cnblogs.com/gw811/archive/2012/10/25/2736224.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值