说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

关一个关于C++模板的问题

编辑:说三道四文库 发布时间:2017-09-26 11:58
HTML文档下载 WORD文档下载 PDF文档下载
现在我有一个接口,比如说是 
class ISupportInitialize
{
public:
    virtual void Initialize() = 0;    
}

然后有一个模板函数
template<class T> void function( T t );
 在函数中我想根据T是否从接口派生做一些不同的事,比如说T从ISupportInitialize派生,
我就调用 t.Initialize() 方法,否则就不调用。

请问题如何实现这样的功能
namespace __inner
{
    template<typename _T> char fun(_T*);
    template<typename _T> long fun(...);
}

template<typename _Base, typename _Sub>
struct is_same_type
{
    enum{value = sizeof(char) == sizeof(__inner::fun<_Base>((_Sub*)0)) };
};


class ISupportInitialize
{
public:
virtual void Initialize() = 0;
};

class Foo: public ISupportInitialize
{
public:
    virtual void Initialize(){ cout<<"Initialize"<<endl; };
};

template<bool>
class dispatcher
{
public:
    template<typename _T>
    dispatcher(_T& r){}
};

template<> class dispatcher<true>
{
public:
    template<typename _T>
    dispatcher(_T& r)
    {
        r.Initialize();
    }  
};

template<class T> void function( T t )
{
    (dispatcher<is_same_type<ISupportInitialize, T>::value>(t));           
}

int main()
{
   Foo x;
   int y;
   function(x);
   function(y);
}
template<typename _T> char fun(_T*);
template<typename _T> long fun(...);
第三次看到这个用法了,很是巧妙..
学习
学习ing
谢谢 Jinhao(辣子鸡丁·新年新气象) ,我现在正在看 Modern C++ Design 这本书,里面关于模板的介绍真是让人大开眼界。以后还要多向你请教 :)
>>template<> class dispatcher<true>
改成template<> class dispatcher<false>
为什么连编译都过不了, 请高手解释!(只要求能编译, 不管逻辑是否正确)

写的很好,佩服!
template<typename _T> char fun(_T*);
template<typename _T> long fun(...);
这个技巧到处都有,并不稀奇,但是整体封装的挺好的!
谁来答答我上面的问题
http://community.csdn.net/Expert/topic/4552/4552060.xml?temp=9.527224E-02
答案找到了...本贴的偏特化编译用得好!
全特化 -_-!
mark
呵呵,鸡丁好像很喜欢特化。佩服。

namespace __inner
{
    template<typename _T> char fun(_T & t){};
    template<typename _T> long fun(...){};
}

template<typename _Base, typename _Sub>
bool is_derived_from(_Sub & s)
{
    return sizeof(char) == sizeof(__inner::fun<_Base>(s)); 
}


class ISupportInitialize
{
public:
virtual void Initialize() = 0;
};

class Foo: public ISupportInitialize
{
public:
    virtual void Initialize(){ cout<<"Initialize"<<endl; };
};

void main()
{
    Foo f;
    if(is_derived_from<ISupportInitialize>(f))
             f.Initialize();

}
可以看看Boost提供的那些对于类型判断的模板,。
不过还是很佩服前面几位的代码。
利用模板偏特化可以实现
int main()
{
    Foo f;
    if(is_derived_from<ISupportInitialize>(f))
             f.Initialize();
}

其实这样来判断,这段代码就失去意义了。如果f没有Initialize,那么将导致一个编译错误
学习
(=_=)
真他们的越来越佩服鸡丁了 (=_=)
学习
#include<iostream>
using namespace std;

namespace __inner
{
template<typename _T> void  fun(_T*t){ t->Initialize();}
template<typename _T> void  fun(...){cout<<"...."<<endl;}
}
class ISupportInitialize
{
public:
virtual void Initialize() =0;
};

class Foo: public ISupportInitialize
{
public:
int i;
void Initialize(){ cout<<"Initialize:  "<<i<<endl; };
};


template<typename T>
void Proxy(T t)
{
__inner::fun<ISupportInitialize>(&t);
}
int main()
{
Foo x;
x.i=10;
int y=0;

Proxy(x);
Proxy(y);
}

唉,研究了一下,做了个变体出来,供参考
鸡丁啊......................(=_=)
SammyLan...你把要做的事情移到了fun里面 使得更直接一点. 但是有时可能太直接了也不便于扩展,或者另做它用.呵呵
其实这样来判断,这段代码就失去意义了。如果f没有Initialize,那么将导致一个编译错误
------------

NO, 如果本身f没有Initialize,它的基类也必须要有,否则在定义Foo f的时候就会因为包含了纯虚函数而出错,到不了后面判断的那一步。

所以基本上个人认为判断“Foo是不是ISupportInitialize”的派生类,就可以完成90%以上的“Foo有没有已实现的Initialize”的判断了,

我倒是觉得,如果是一个private 继承,似乎是没有办法了。但作为接口,private继承还是少的。
template<> class dispatcher<true>
{
public:
    template<typename _T>
    dispatcher(_T& r)
    {
        r.Initialize();
    }  
};

template<class T> void function( T t )
{
    (dispatcher<is_same_type<ISupportInitialize, T>::value>(t));           
}
-------------------------------
认真看了一下,其实这一段跟俺那一段不是等价的么?is_same_type<>::value得到true或者false,然后根据true/false决定是否调用t.Initialize()


不过你说的那个问题是对的,就是说,如果Foo本身没有实现Initialize(),但是其基类曾经实现过,比如:

class ISupportInitialize
{
public:
virtual void Initialize() = 0;
};

class Temp: public ISupportInitialize
{
public:
    virtual void Initialize(){ cout<<"Initialize"<<endl; };
};

class Foo: public Temp
{
};
 
这个时候就会很糟糕,换一种方式可能会好一些。

void main()
{
    Foo f;
    if(is_derived_from<ISupportInitialize>(f))
    {
        ISupportInitialize * pBase = &f;
        pBase->Initialize();
    }

}

什么是特化?
鸡丁兄。请教一下。。小弟看不明白
(dispatcher<is_same_type<ISupportInitialize, T>::value>(t));   
这里的外层括号的作用是什么??
(dispatcher<is_same_type<ISupportInitialize, T>::value>(t));
这里。相当于
dispatcher<is_same_type<ISupportInitialize, T>::value>  _dispatcher(t);
术语上我不知道要怎么解释。。但是外层括号的作用就是省掉定义一个对像

不知道我这样说正不正确。。
外层的括号可以去掉。

 xxxdg(学习中) 的代码
如果Foo 不是从ISupportInitialize派生,则你的程序编译会不通过。
 Jinhao的代码是利用了模板的一个特性:如果一段模板代码没有被用到,则它不会被编译。所以不会报编译借
(dispatcher<is_same_type<ISupportInitialize, T>::value>(t));
最外边这一层括号不能去掉
如果要去掉最外层的话,那么就必须这么写
dispatcher<is_same_type<ISupportInitialize, T>::value> _dispatcher(t);

其中上面这段和下面的等同
dispatcher<is_same_type<ISupportInitialize, T>::value> (_dispatcher)(t);

所以,如果去掉最外面层,
dispatcher<is_same_type<ISupportInitialize, T>::value>(t);
其实就是
dispatcher<is_same_type<ISupportInitialize, T>::value> t;

最后在来看看 function
template<class T> void function( T t )
{
(dispatcher<is_same_type<ISupportInitialize, T>::value>(t));
}
如果去掉最外层括号,那么就成了
template<class T> void function( T t )
{
  dispatcher<is_same_type<ISupportInitialize, T>::value> t;//t?重复定义!
}
MK
That is not important.
It is a never-committed crime.
---------------------------------
int main(int argc, char *argv[])
{
    Foo f;
    if(is_derived_from<ISupportInitialize>(f))
    {
        ISupportInitialize * pF = (ISupportInitialize *)&f;
        pF->Initialize();
    }        
    int k;
    if(is_derived_from<ISupportInitialize>(k))
    {
        ISupportInitialize * pF = (ISupportInitialize *)&k;
        pF->Initialize();
    }        
  system("PAUSE");
  return 0;
}
--------------------------------------------------
模板特化是好的,不过我个人认为像条件判断等一些基本语法,还是保留原始语法更好一些,显得简洁。编程风格的问题,Not necessarily. Any way,I have sent my ADMIRATION. :)
MK!
学习
ri.....
枉我自诩学过c++,熟练vc,竟没读懂。。。。
Marissa Mayer为何带雅虎重回门户时代? 开发者最爱的三款开发工具 Facebook开源JavaScript库:React 硬件天堂深圳行:从Seeed Studio、Knewone到柴火创客空间 消费应用开发难赚钱?做个企业app store吧 开发开源软件的智慧:够简单,很好用 历届中国云计算大会PPT集萃(终章):架构到实践的全面解析 透过现象看本质:详谈数据可视化 专家观点:HTML5无法彻底抹杀Native应用 Google地图工程主管Raj Shah跳槽至微软在线服务部门 微软证实Windows 8.1引入类“开始”按钮 系统6月26日开放下载 PHP开发者意向调查:移动开发+云服务成为焦点 研发周报:16种折磨开发者的方式 移动周报:Jolla和Sailfish OS,那些你应该知道的事儿 优化技巧分享:把内存消耗降低至原来的1/20 85后程序员:独自一人,完成一个HTML5开源图形库 关于Waze的前世今生,你所不知道的事 代码审查——提高代码质量的终极武器 值得开发者关注的8个HTML5 API 最初设计方案大公开!LINE STAMP 贴图诞生记 安全宝联合华为成立抗D联盟 储备防御带宽达110G 专访中科院贾海鹏:给异构开发者的六个建议 我们死后的遗留数据将会如何处理? 传微软考虑重大重组 或势在必行 云适配CEO陈本峰:8年磨一剑 Splashtop企业应用:SplashApp让办公移动起来 时空旅行+内付费“植物大战僵尸2”下月18日全球同步发行! 中移动推网络电话Jego 后来者能否居上? 防止数据泄露:BYOD下的管理员5大妙招 咕咚副总裁司建铭谈移动时代的“软硬整合” 未来的物联网结点:可穿戴设备 错误分析,高分求解!! 各位大虾,帮帮忙!求助如何实现网页访问者的人数 有一个查询问题.快进来.进来有分. 重装Win系统后如何进入Linux系统?? 谁能帮我画这个图??给20分,真的给. 表格中的回车那里去了? 能把这样的VBS脚本改写为VB代码吗? 2000无故奇怪死机! 能把这样的VBS脚本改写为VB代码吗?? 非典时期,你流过几次泪了,我们还需要感动多少次? 先问一下实现性:手机能发送图片,avi和声音吗 2000和xp 共享的问题? 怎么通过netmeeting连上广域网的主机? 能不能将一个文件夹下的图片进行批量上传? 字符串问题: 有关结束进程的问题 谢谢高手 怎样才能学好c语言这门课 帮帮我吧—— 一个简单的问题! 怎样调用Twain设备照相,并将照片放在一个picturebox中 怎样在数据表中查询在某个范围内共有几条记录?(好象很弱的问题) 一个jbuilder的问题[求助] default.asp有IFRAME里面包含list.asp页,list.asp里的链接如何给default.asp传递一个值并刷新它? ★★★如何在界面线程中调用主线程的对象★★★ 如何让jbuilder生成的文件,在没有jbuilder环境的机器上运行? 有人能吧“准女友胸太平”和“一个程序员的艳遇”粘贴后发成贴子吗,我的机子配置差,打不开。估计这种方法可以。谢谢 问有关窗体的参数属性 学计算机的是不是出去闯比较好!但是听到很多大学同学讲,在外面也不容易!很矛盾! ?WSAWaitForMultipleEvents如何退出 在ASP.net怎么用MessageBox啊?? 俺向大家请教一个问题,可以送分! 真无奈,恳求大家帮我! 接下来我应该干什么????!!! 小女子关于数据库连接的一点看法,请指教 请问如何将一个结构体和listview绑定??绑定后listview是不是相当于一个结构体数组 请问各位兄弟:怎样在 本地机打开XML语言的网页 如何在数据窗口的列名的上方家一行标题, 200分寻找fastReport,有的快进。 关于打印的问题 how are you?????????????????/ 一个小问题,请大家帮帮忙! 如何才能实现左边导航条菜单的样子?(www.csdn.net 左边的) JBuilder7.0+weblogic7.0+jsp+编译时为何出错???? 提取文件信息 配置我感兴趣论坛里面的Dreamweaver写成Dreamwaver 在delphi的form中如何根据登陆用户的权限disable/enable Form中的控件 打印问题 请教各位gg很菜很菜的怪怪问题~~~~~~~~~~~*^-^* 关于函数调用 一个有关文件名的问题 为什么出现这种错误?? javascript高手请进!!! 华人男子失业 纽约杀表嫂一家5口提审奥巴马社交账户被黑 其遭批“监听世界美国起诉英国黑客盗取机密文件 英当局津巴布韦男子蝉联最丑先生 自称丑与生美参院情报委员会主席吁对美情报工作大澳洲一名男子失踪4天期间靠吃昆虫喝池美国监听风波陷两难 白宫急灭火共和党克里说伊朗应以行动证明核计划用于和平中国海军“杀手锏”伊美关系转暖尚需时日加拿大12岁黑客攻击网站只为换取电脑美国监听风波陷两难 白宫急灭火共和党英国女子不愿找工作 靠生育9名子女领美国国务卿克里暗示未来几周内将出访埃卜拉希米:阿萨德可为建设新叙利亚作出新闻分析:阿根廷议会选举释放的政治信《卫报》持续揭美监控丑闻 卡梅伦称难澳洲一名男子失踪4天期间靠吃昆虫喝池美国国务卿克里暗示未来几周内将出访埃美国起诉英国黑客盗取机密文件 英当局英国女子不愿找工作 靠生育9名子女领手镯还有那么多门道,我也是醉了特稿:谁偷走了中东这五年海南省建设项目规划设计研究院团员青年讽刺?四川队出发训练 赛区安保明显加广日电梯成立研发中心 建立行业顶级实李嘉诚基金会捐资助女性探索工作发展新广西构筑大通关体系 打造面向东盟国际博鳌亚洲论坛硬件升级违禁药冒充玻尿酸,微整形美容如何成““有个煤气灶,就能开餐饮店吗?” 网上海边检回应“女子归国航班被骂中国猪精准:创业暴涨、巨头重磅暗示!周五只由机器人“解开”的婚礼密码 你Get老美“劈腿”小安 日元贬值会成功垫脚最新时尚中国风旗袍-时尚女神穿衣搭配荐号 | 什么叫“床品”?像狗一样被锁链捆住的那群印尼人当“干女儿”不为钱,还能为了啥其实她们根本就没穿胸罩翡翠收藏你已经陷入误区了律师支招 | 90家上市公司被开罚单
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘