C++类模板的模板成员函数数求解

C++函数模板非类型参数的使用介绍
用圣才电子书APP或微信扫一扫,在手机上阅读本文,也可分享给你的朋友。
C++编程语言中的模板应用是一个非常重要的应用技术,我们曾经通过多篇文章对此进行过详细的介绍。那么今天我们就先来了解一下有关C++函数模板非类型参数的一些基本概念,方便大家理解。
C++函数模板非类型参数主要用来为函数提供一个运算常量。关于非类型的函数模板参数,书中有下面的例子:
1.&//函数模板定义&
2.&template&typename T, int VAL&
3.&T addValue(T const& x)&
5.&return x + VAL;&
7.&//其他代码&
8.&//函数模板的使用&
9.&std::transform(source.begin(), source.end(), dest.begin(),&
10.&(int(*) (int const&))addValue&int, 5&);
上面的代码中定义了一个函数模板,目的是对传入的参数加上一个指定的int型的5。这样的函数被普遍的使用在对一组数据进行同一处理的场合。例如,12行。这里需要注意的是:一std::transform函数本身就是一个模板函数,它的最后一个参数可以传递一个函数指针。
因此,(int(*) (int const&))addValue&int, 5&其实是一个指向实例化后的addValue&T, int VAL&模板函数的指针。至于这个指针怎么读,还请高手指教。另外需要注意的一点是,std::transform的最后一个参数不一定要是模板函数,任何函数都可以(关于std::transform的正确理解参考下面的评论)。只是模板函数更合适处理多种类型的数据罢了。
C++函数模板非类型参数的限制。
关于非类型模板参数的限制目前记住它可以是常整型(包括枚举类型)和指向外部连接对象的指针就可以可了。由于历史原因,浮点型不能作为非类型模板的参数;而指针和字符串作为非类型模板的参数是有条件的。我想这与变量的作用范围和生命周期有关吧。书中后面会有比较相信的介绍,就等到时候再细看了。
  来源:网络&&&&&&& 作者:不详
小编工资已与此赏挂钩!一赏一分钱!求打赏↓ ↓ ↓
如果你喜欢本文章,请赐赏:
已赐赏的人
我的电子书& Member Function Templates(成员函数模板)
Member Function Templates(成员函数模板)
Member Function Templates翻译成中文就是成员函数模板,这个东西我个人见得少,最初是在STL的auto_ptr源代码里面看到的,当时候也不是很明白;这几天又翻了翻《More Effective C++》,正好看到上面介绍的比较详细,就找了点资料总结一下。
为了更好的说明问题,我们自己定义一个Smart Pointer(智能指针,这里只是示例,所以定义是不完整和不完善的),假设现在我们手上有这样三个类:MusicProduct、CD、MP3,类之间的关系图如下:(Visual Studio自动生成的类图,效果还不错,以前一直不知道Visual Studio也有这个功能)
我们定义的智能指针SmartPtr如下:
template&class T&
class SmartPtr
explicit SmartPtr(T* realPtr = NULL) : pointee(realPtr){}
T* operator-&() const
return pointee;
T& operator*() const
return *pointee;
T* pointee;
现在有一个播放函数:
void displayAndPlay(const SmartPtr&MusicProduct&& pmp, int times)
for (int i = 1; i &= times; ++i)
pmp-&displayTitle();
pmp-&play();
如果有下面这样的调用,会不会有什么问题呢?
int main(int argc, char **argv)
CD *cd = new CD(&BEYOND LIVE CD&);
MP3 *mp3 = new MP3(&BEYOND MP3&);
SmartPtr&CD& cdMusic(cd);
SmartPtr&MP3& mp3Music(mp3);
displayAndPlay(cdMusic, 10);
displayAndPlay(mp3Music, 10);
实际编译时会发生错误,在Visual Studio 2008下面提示如下错误:
1&error C2664: “displayAndPlay”: 不能将参数 1 从“SmartPtr&T&”转换为“const SmartPtr&T& &”
T=MusicProduct
提示“SmartPtr”不能转换为“const SmartPtr &” 。因为在编译器眼里SmartPtr和SmartPtr是两个完全不相关的东西,他们之间没有继承关系。我们可以写一个隐式类型转换,但实际操作起来不太理想,正如前面所说,STL的auto_ptr采用了Member Function Templates(成员函数模板)技术。我们可以再SmartPtr的定义中增加成员函数模板实现代码,具体如下:
template&class T&
class SmartPtr
explicit SmartPtr(T* realPtr = NULL) : pointee(realPtr){}
T* operator-&() const
return pointee;
T& operator*() const
return *pointee;
// Member Function Templates
template&class newType&
operator SmartPtr&newType&()
return SmartPtr&newType&(pointee);
T* pointee;
之后就可以正常编译和运行了。看起来很神奇吧,看看《More Effective C++》对此的解释:
现在请你注意,这可不是魔术——不过也很接近于魔术。假设编译器有一个指向 T 对象的智能指针,它要把这个对象转换成指向“T 的基类”的智能指针。编译器首先检查 SmartPtr的类定义,看其有没有声明明确的类型转换符,但是它没有声明。编译器然后检查是否存在一个成员函数模板,并可以被实例化成它所期望的类型转换。它发现了一个这样的模板(带有形式类型参数 newType) ,所以它把newType绑定成 T 的基类类型来实例化模板。 这时,惟一的问题是实例化的成员函数代码能否被编译:传递指针 pointee 到指向“T 的基类”的智能指针的构造函数,必须合法的。指针pointee 是指向 T 类型的,把它转变成指向其基类(public 或 protected)对象的指针必然是合法的,因此类型转换操作符能够被编译,可以成功地把指向 T 的智能指针隐式地类型转换为指向“T 的基类”的智能指针。
1. Member Function Templates是C++的一个新特性,可能有些编译器并不支持这个特性,比如VC6,编译时似乎完全忽略了我们新加入的Member Function Templates代码。仍然会提示如下错误:
--------------------Configuration: MftDemo - Win32 Debug--------------------
Compiling...
MemFunTmp.cpp
g:\w7documents\visual studio 6.0\projects\mftdemo\memfuntmp.cpp(87) : error C2664: 'displayAndPlay' :
cannot convert parameter 1 from 'class SmartPtr&class CD&' to 'const class SmartPtr&class MusicProduct& &'
Reason: cannot convert from 'class SmartPtr&class CD&' to 'const class SmartPtr&class MusicProduct&'
No constructor could take the source type, or constructor overload resolution was ambiguous
g:\w7documents\visual studio 6.0\projects\mftdemo\memfuntmp.cpp(88) : error C2664: 'displayAndPlay' :
cannot convert parameter 1 from 'class SmartPtr&class MP3&' to 'const class SmartPtr&class MusicProduct& &'
Reason: cannot convert from 'class SmartPtr&class MP3&' to 'const class SmartPtr&class MusicProduct&'
No constructor could take the source type, or constructor overload resolution was ambiguous
执行 cl.exe 时出错.
MftDemo.exe - 1 error(s), 0 warning(s)
2. MS关于Member Function Templates的更多一些介绍
/en-us/library/swta9c6e.aspx
3. 本文的完整源代码下载
作者:代码疯子(Wins0n) 本站内容如无声明均属原创,转载请保留作者信息与原文链接,谢谢!
您可能对下面的文章也感兴趣:
(推荐使用
(关于作者 Wins0n/代码疯子)
免责声明:本站所有内容仅代表个人观点,无法保证100%准确,如有错误请联系指正,谢谢!
2016年三月 &(1)
2016年二月 &(1)
2016年一月 &(1)
2015年十月 &(1)
2015年六月 &(2)
2015年四月 &(1)
2015年一月 &(1)
2014年十一月 &(5)
2014年十月 &(1)
2014年九月 &(1)
2014年八月 &(2)
2014年七月 &(3)
2014年六月 &(4)
2014年四月 &(1)
2014年三月 &(2)
2014年二月 &(1)
2014年一月 &(1)
2013年十二月 &(1)
2013年十一月 &(2)
2013年十月 &(2)
2013年九月 &(3)
2013年八月 &(2)
2013年七月 &(3)
2013年六月 &(2)
2013年五月 &(1)
2013年四月 &(4)
2013年三月 &(2)
2013年二月 &(1)
2013年一月 &(2)
2012年十二月 &(5)
2012年十一月 &(3)
2012年十月 &(3)
2012年九月 &(4)
2012年八月 &(4)
2012年七月 &(3)
2012年六月 &(3)
2012年五月 &(6)
2012年四月 &(4)
2012年三月 &(6)
2012年二月 &(4)
2012年一月 &(7)
2011年十二月 &(9)
2011年十一月 &(9)
2011年十月 &(13)
2011年九月 &(18)
2011年八月 &(8)
2011年七月 &(7)
2011年六月 &(16)
2011年五月 &(13)
2011年四月 &(21)
2011年三月 &(22)
2011年二月 &(15)
2011年一月 &(7)
2010年十二月 &(23)
2010年十一月 &(33)
2010年十月 &(35)
2010年九月 &(42)C++模板的定制四:定制成员函数和缺省类参-c/c++-电脑编程网C++模板的定制四:定制成员函数和缺省类参作者:Sanda 和相关&&
C++模板的定制四:定制成员函数和缺省类参
一、&&&&&&&&&&&& 定制成员函数
定制模板类成员函数,就是定义一个指定类型的类成员函数取代模板类定义的成员函数,实现特殊的功能,从而完成模板类成员函数的定制。
&&&&&& template &typename T&
&&&&&& class classname
{
&&&&&& public:
&&&&&& &&&&&& classname(T t):_val(t){}
~classname(){}
void display();
private:
T _
};
&
template &typename T&
void classname&T&:: display()
{
&&&&&& cout&&_val&&
}
上面是一个classname 类的声明,classname 类中有个display()函数,它输出成员_val到控制台。下面我们就来定制classname 类中的display()函数,使其有不同的表现。、//定制成员display()函数:
void classname&char*&:: display()
{
&&&&&& if(NULL==_val)
cout&&”No Content”&&
else
cout&&_val&&
}
这就是classname 类中成员函数display()的char*类型定制成员函数。
&&&&&& 二、模板类的缺省类参
&&&&&&&&&&&&& 在声明一个模板类时,其类参可以提供缺省值。
&&&&&& &&&&&& template &typename T=int&
&&&&&&&&&&&&& class classname
{
&&&&&& public:
&&&&&& &&&&&& T _
};
声明一个类classname对象可以两种形式。
1.classname&double& obj1;&&&&&&&&&&&&& &&&&&& //以double为参数声明一个变量
2.classname obj2;&&&&&& &&&&&&&&&&&&& &&&&&&&&&&&&& //以缺省类型int为参数声明一个变量
文章写的仓促,有错别字或错误请大家多批评指出。谢谢大家的捧场,在下感激不尽,欢迎和大家交流 (-----袁凯-----)。
相关资料:|||||||C++模板的定制四:定制成员函数和缺省类参来源网络,如有侵权请告知,即处理!编程Tags:                &                    c++ 类模版、成员函数模版、函数模版 用法 - DoubleLi - 博客园
C++函数模版与类模版。
template &class T&
void SwapFunction(T &first, T &second){
}//函数模版
template &class T&//类模版
class CTemplate{
& & void SWap(T &first, T &second){
#include &iostream&
class Single{
static Single*
ShareInstance();
static void ReleaseInstance();
template&class Tex&//要成员函数实现模版用法,而类不是模版类。需要写成这个格式
void SwapEx(Tex &obj1, Tex &obj2){
~Single();
Single(const Single &other);
Single& operator=(const Single &other);
static Single *m_pO
Single* Single::m_pObj = NULL;
Single* Single::ShareInstance(){
if (NULL == m_pObj) {
m_pObj = new Single();
return m_pO
void Single::ReleaseInstance(){
if (m_pObj) {
delete m_pO
m_pObj = NULL;
Single::Single(){
Single::~Single(){------解决方案--------------------答案我记得写在《C++&templates》上,自己认真翻翻吧。
我记得是:不可以。但是,我听说部分编译器扩展支持。------解决方案--------------------class&A
template&&class&T&
void&func(T&t)&{cout&&&&t;}
int&main()
a.func(100);
}------解决方案--------------------
template&class&T,&unsigned&B&
class&Base
void&Func()
if&(B&==&16)
cout&&&&"helloworl";
int&_tmain(int&argc,&_TCHAR*&argv[])
Base&int,16&&
base.Func();
//输出helloworld------解决方案--------------------引用:引用:
试一下这个呗,其实没太看明白你到底要干什么。
C/C++&code
#include&&iostream&
template&class&T,&unsigned&B&
struct&Base
void&Func&()&{&std::cout&&&&"primary"&&&&std::&}
template&&cla
我的这个类有很多函数,但只有一个函数的实现需要依赖于第2个值参数,如果把整个类特化就得把其它所有的函数代码复制一遍。
我想实现的就是#16的效果,只是想通过在编译期的模板实现
哦,这样啊。那得复杂点,试试下面这个吧。
#include&&iostream&
&template&&bool,typename&=&void&&struct&enable_if&{&};
&template&&typename&T&&struct&enable_if&true,T&&{&typedef&T&&};
template&class&T,&unsigned&B&
struct&Base
&template&&unsigned&N&=&B&
&typename&::enable_if&16!=N&::type
&Func&()&{&std::cout&&&&"primary"&&&&std::&}
&template&&unsigned&N&=&B&
&typename&::enable_if&16==N&::type
&Func&()&{&std::cout&&&&"specialization"&&&&std::&}
int&main&()
&&Base&int,0&&b;
&&b.Func();
&&Base&int,16&&b;
&&b.Func();
&return&0;
------解决方案--------------------默认函数模板参数需要c++0x的支持。
常规的,不过很别扭,毕竟是反的。
template&&class&T,&unsigned&B&&class&B
template&&class&T&&class&Base&T,&16&&{&};
template&&class&T,&unsigned&B&&class&Base&:&public&Base&T,&16&&{&};------解决方案--------------------内部函数对象的话,如果要访问外部对象成员,又得多费手脚了。
传统的switch-case反倒是最一目了然的方法。------解决方案--------------------解决“方案”离问题本身越来越远,越来越复杂,也就越来越丑陋。------解决方案--------------------引用:我的2010过不去啊,你用SP1?
怎么说呢,刚才确实编译通过了,还运行了
template&class&T,&unsigned&B&
class&SpecialValue
void&Func();
template&class&T,&unsigned&B&
void&SpecialValue&T,B&::Func()
printf("Template&Specialization&Normal\n");
template&class&T&
void&SpecialValue&T,16&::Func()
printf("Template&Specialization&Value:16\n");
错误的话,那这个呢?
template&class&T&
class&SpecialType
void&Func();
template&class&T&
void&SpecialType&T&::Func()
printf("Template&Specialization&Type::Normal\n");
template&&
void&SpecialType&long&::Func()
printf("Template&Specialization&Type::long\n");
------解决方案--------------------引用:引用:
你不是在&#22&已经“大功告成”了吗,怎么这会又说目标实现不了了? 共&2&页:
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有

我要回帖

更多关于 成员函数模板特化 的文章

 

随机推荐