C++模板,判断是否存在成员函数,实现差异化操作
2014-11-25 16:22
375 查看
工作中遇到一个问题,我有一个容器,装着各式各样的对象的指针,需要把拥有dump方法的指针内容dump出去,而对于没有dump方法的对象,直接忽略。
首先想到的是给每个对象提供一个查询操作,从而得知是否拥有dump方法。显然这个方法不能让人满意,需要更改大量的class实现。C++如果我能自动判断某个类型是否拥有某方法,这个问题可以完美的解决,因为是否含有某方法编译期已经确定了,所以是有可能通过一些技巧来实现这个功能的。
查阅了大量的模板偏特化,匹配失败不是错误,终于找到了Mr.Right:
废话不多说,贴代码:
www.huaqiangu6.com
检测是否有定义 void hello():
点击(此处)折叠或打开template<typename T>
struct has_hello{
template<typename U, void (U::*)()> struct HELPS;
template<typename U> static char Test(HELPS<U, &U::hello>*);
template<typename U> static int Test(...);
const static bool Has = sizeof(Test<T>(0)) == sizeof(char);
}
测试:
点击(此处)折叠或打开struct A
{
void hello(){
cout<<"A is Hello."<<endl;
}
int x;
};
int main()
{
cout<<"A has hello? "<<has_hello<A>::Has<<endl;
}
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() 方法。
首先想到的是给每个对象提供一个查询操作,从而得知是否拥有dump方法。显然这个方法不能让人满意,需要更改大量的class实现。C++如果我能自动判断某个类型是否拥有某方法,这个问题可以完美的解决,因为是否含有某方法编译期已经确定了,所以是有可能通过一些技巧来实现这个功能的。
查阅了大量的模板偏特化,匹配失败不是错误,终于找到了Mr.Right:
废话不多说,贴代码:
www.huaqiangu6.com
检测是否有定义 void hello():
点击(此处)折叠或打开template<typename T>
struct has_hello{
template<typename U, void (U::*)()> struct HELPS;
template<typename U> static char Test(HELPS<U, &U::hello>*);
template<typename U> static int Test(...);
const static bool Has = sizeof(Test<T>(0)) == sizeof(char);
}
测试:
点击(此处)折叠或打开struct A
{
void hello(){
cout<<"A is Hello."<<endl;
}
int x;
};
int main()
{
cout<<"A has hello? "<<has_hello<A>::Has<<endl;
}
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() 方法。
相关文章推荐
- 实现gridview中checkbox 模板列单选操作和.cs中判断checkbox是否选中
- C++文件与文件夹操作(1)--判断文件和文件夹是否存在
- 利用 c++模板 类型 推导思想,实现最简单的 判断两个类型 是否一样的 方法
- C++基础:怎样判断某一文件是否存在
- 判断用户是否存在(通过参数来实现)
- 使用jquery实现判断用户名是否存在的实例
- Unix C中的一些文件操作(判断是否存在,文件打开,删除等)
- How to know is the file exist in C++ - 在C++中如何判断文件是否存在
- 如何在C++中实现对输入数是否为小数的判断
- c++ 判断文件夹是否存在
- 判断记录是否存在和日期差操作
- C/C++中判断某一文件或目录是否存在
- 判断用户是否存在(通过参数来实现)
- 简单的方法实现判断Mysql内某个字段Fields是否存在
- JavaScript判断远程图片是否存在,加载完成:onerror 属性- & jQuery实现(如果因为网络或图片的原因发生异常,则显示该图片)~
- 【转】c# 注册表操作,创建,删除,修改,判断节点是否存在
- 判断一个有向图中是否存在一个环(C++代码)
- C++ 判断文件是否存在
- c/c++ c++ file c++/stl/boost 判断文件目录是否存在
- C/C++中判断某一文件或目录是否存在