• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > C++ 11实现检查是否存在特定的成员函数

C++ 11实现检查是否存在特定的成员函数

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c++ 成员函数,c++静态成员函数,c++常成员函数,c++静态数据成员,c++静态成员变量等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

问题提出

最近工作中遇到这样一个需求:实现一个ToString函数将类型T转换到字符串,如果类型T中含有同名方法ToString则直接调用。

这样一个ToString实现可以使用std::enable_if来做到,但是这里的难点在于如何判断类型T中存在这样一个ToString方法,以便可以放入enable_if中做SFINAE。

检查类中是否存在特定成员

相同的问题在知乎上有人提出过,@孙明琦的答案提供了一个用于检测特定检测子U在类型T下是否有效的检测器is_detected_v。其中用到了一个C++17的std::void_t,考虑到目前C++17还没得用,这个实现只作参考之用(事实上C++17自带了一个这样的检测器,并不需要自己写这样的模板)。

经人提醒,我参考了下标准库在实现swap上做的努力,看到了这样的写法:

namespace __swappable_details {
 using std::swap;
 
 struct __do_is_swappable_impl
 {
  template <typename _Tp, typename
    = decltype(swap(std::declval<_Tp&>(), std::declval<_Tp&>()))>
  static true_type __test(int);
 
  template <typename>
  static false_type __test(...);
 };
}
 
template <typename _Tp>
struct __is_swappable_impl
 : public __swappable_details::__do_is_swappable_impl
{
 typedef decltype(__test<_Tp>(0)) type;
};
 
template <typename _Tp>
struct __is_swappable
 : public __is_swappable_impl<_Tp>::type
{};
</div>

简单分析可以看到__is_swappable被用来检查是否存在一个swap函数接受T作为参数,很有趣的是__test函数,如果存在swap函数满足条件,那么test(int)这个重载版本就会被选中。而如果不满足条件,因为推导失败就剩下了test(…)这个版本。通过这一手段,再设置下返回值分别为true和false,就实现了这样的一个检测过程。

按图索骥,检查是否存在成员ToString的模板就可以这么写:

namespace details
{
 struct HasMemberToStringValidator
 {
  template <typename T, typename = decltype(&T::ToString)>
  static std::true_type Test(int);
 
  template <typename>
  static std::false_type Test(...);
 };
}
 
template <typename T>
struct HasMemberToString :
 public decltype(details::HasMemberToStringValidator::Test<T>(0))
{};
</div>

HasMemberToString::value就是T中是否存在该成员的计算结果。

检测是否存在特定成员函数

但是上述代码有个问题,如果类T中的ToString是个成员变量,上述检测也会返回true。

解决这一问题的手段是去调用T::ToString,如果这个ToString可以被调用并能生成返回值,就认为这是个成员函数(严谨的讲,这个过程是确认T::ToString是callable的,但是callable的玩意不一定就是成员函数,然而实际使用并不需要这样细分)。

这里的另一个问题是,因为ToString是成员函数,那么decltype(T::ToString())这种手段就行不通了,因为成员函数必须带对象进行调用。既然必须要一个对象,那么这里的解决方法就是用上declval来产生一个对象,再用decltype获取返回值类型。

按照这个思路,验证过程被改动成:

struct HasMemberToStringValidator
{
 template <typename T, typename U =
  typename std::decay<decltype(std::declval<T>().ToString())>::type,
  typename = typename std::enable_if<std::is_same<std::string, U>::value>::type>
 static std::true_type Test(int);
 
 template <typename>
 static std::false_type Test(...);
};
</div>

这个升级版本除了能检查是否存在成员函数ToString以外还对返回值做了限定,确保返回的是string。以此类推,还能检查返回是否是u16string、u32string。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C++中判断成员函数是否重写
  • C++ 11实现检查是否存在特定的成员函数
  • 关于C++中定义比较函数的三种方法小结
  • 深入理解c++常成员函数和常对象
  • C++中基本的输入输出函数使用指南
  • 浅析C和C++函数的相互引用
  • 浅析c/c++中函数的参数传递
  • C与C++ 无参函数的区别解析
  • 在c和c++中实现函数回调
  • 探讨:C++中函数返回引用的注意事项

相关文章

  • 2017-05-28使用WindowsAPI实现播放PCM音频的方法
  • 2017-05-28详谈C++何时需要定义赋值/复制构造函数
  • 2017-05-28图文详解C语言位运算基础知识
  • 2017-05-28八皇后问题的相关C++代码解答示例
  • 2017-05-28解析C++中构造函数的默认参数和构造函数的重载
  • 2017-05-28C++友元函数与拷贝构造函数详解
  • 2017-05-28归并排序的递归实现与非递归实现代码
  • 2017-05-28C++使用ADO实现存取图片的方法
  • 2017-05-28C语言关键字auto与register的深入理解
  • 2017-05-28C/C++字符串函数之复制函数详解

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 二叉搜索树源码分享
    • C语言中设置进程优先顺序的方法
    • C语言实现稀疏矩阵
    • C++三色球问题描述与算法分析
    • 深入sizeof的使用详解
    • 使用C语言求二叉树结点的最低公共祖先的方法
    • c++类构造函数详解
    • 基于C++ map中key使用指针问题的详解
    • C++用Dijkstra(迪杰斯特拉)算法求最短路径
    • C++中函数的默认参数详细解析

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有