Chinaunix首页 | 论坛 | 博客
  • 博客访问: 488952
  • 博文数量: 174
  • 博客积分: 130
  • 博客等级: 入伍新兵
  • 技术积分: 587
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-12 19:39
文章分类

全部博文(174)

文章存档

2018年(2)

2016年(10)

2015年(6)

2014年(31)

2013年(92)

2012年(33)

我的朋友

分类: C/C++

2014-12-03 21:50:25

工作中遇到一个问题,我有一个容器,装着各式各样的对象的指针,需要把拥有dump方法的指针内容dump出去,而对于没有dump方法的对象,直接忽略。

首先想到的是给每个对象提供一个查询操作,从而得知是否拥有dump方法。显然这个方法不能让人满意,需要更改大量的class实现。C++如果我能自动判断某个类型是否拥有某方法,这个问题可以完美的解决,因为是否含有某方法编译期已经确定了,所以是有可能通过一些技巧来实现这个功能的。

查阅了大量的模板偏特化,匹配失败不是错误,终于找到了Mr.Right:
废话不多说,贴代码:

检测是否有定义  void hello():

点击(此处)折叠或打开

  1. template<typename T>
  2. struct has_hello{
  3.     template<typename U, void (U::*)()> struct HELPS;
  4.     template<typename U> static char Test(HELPS<U, &U::hello>*);
  5.     template<typename U> static int Test(...);
  6.     const static bool Has = sizeof(Test<T>(0)) == sizeof(char);
  7. }
测试:

点击(此处)折叠或打开

  1. struct A
  2. {
  3.   void hello(){
  4.     cout<<"A is Hello."<<endl;
  5.   }
  6.   int x;
  7. };


  8. int main()
  9. {
  10.   cout<<"A has hello? "<<has_hello<A>::Has<<endl;
  11. }

 has_hello 能编译通过,而且能工作!!!

解释:
template<typename U> static int Test(...); 能匹配所有的类型U
template<typename U, void (U::*)()> struct HELPS当Type U有hello,且hello的类型为 void (U::*)()时,模板HELPS<U, &U::hello>能正确匹配,否则模板无法匹配

Test<T>(0)  优先匹配 HELPS<U, &U::hello> 因为template<typename U> static char Test(HELPS<U, &U::hello>*是一个特化

sizeof操作符不需要计算表达式的值,是一个编译期的操作,定义指针类型可以只有声明没有定义
所以HELPS和Test都不需要实现,仅有声明就可以通过编译

巧妙的探测了自定义类型A是否含有void U::hello() 方法。


阅读(1430) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~