`
tcspecial
  • 浏览: 896535 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

c++ 检测成员函数

阅读更多

C++ 没有类似Java反射机制,无法动态获取对象元信息,那么如何检测对象是否存在成员函数呢?

 

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

muduo框架中有这样一段代码:

vi muduo/base/Singleton.h

template<typename T>
struct has_no_destroy
{
  template <typename C> 
  static char test(decltype(&C::no_destroy));	// 返回char

  template <typename C> 
  static int32_t test(...);		// 返回int

  const static bool value = sizeof(test<T>(0)) == 1;
};

static void init()
{
	value_ = new T();

	// 判断是否存在no_destroy方法
	if (!detail::has_no_destroy<T>::value)
	{
	  ::atexit(destroy);
	}
}

 

 测试代码:

struct A
{
	// empty
};

struct B
{
	int no_destroy;		// 成员变量	
};

struct C
{
	int no_destroy(){}	// 成员函数
};

void test()
{
	// 匹配test(&A::no_destroy) 时,由于A没有no_destroy方法,理论上应该报错。编译器寻找下一个匹配test(...),因此返回0
	bool p1 = has_no_destroy<A>::value;
	bool p2 = has_no_destroy<B>::value;
	bool p3 = has_no_destroy<C>::value;
	printf("%d %d %d\n", p1, p2, p3); 	// 输出 0 1 1
}

 

上文利用了c++ SFINAE(Substition Failure is not a error) 特性语法,即匹配失败不是错误。在进行模板特化,编译器会返回最佳匹配模板,避免失败。

 

2. 增强版本

上述代码,B的no_destroy成员也可以正常调用,那如何只检测成员函数呢?

成员函数要用对象来调用,可用declval构造对象。

struct check_no_destroy
{
	/**
	 * 1. T 对象
	 * 2. U 获取T::no_destroy()返回值
	 * 3. 返回值类型为int
	 */
	template <typename T, 
	typename U = typename std::decay<decltype(std::declval<T>().no_destroy())>::type, 
	typename = typename std::enable_if<std::is_same<int, U>::value>::type>	
	static std::true_type Test(int);

	template <typename>
	static std::false_type Test(...);
};

template <typename T>
struct has_no_destroy :
 public decltype(check_no_destroy::Test<T>(0))
{
	
};

void test()
{
	/*
	std::true_type = integral_constant<bool, true>;
	显示值::value
	*/

	bool p = hash_no_destroy<D>::value;
	cout << p << endl;		// 1 
}

 

 

 

 

 

分享到:
评论

相关推荐

    C++I/O描述

    介绍了 C++的 I/O( 输入输出 )问题,本文结构清晰,讲解简单易懂,对 C++ 的流模型作为细致...入部分,介绍了 cin 流,输入时的错误检测机制,及使用输入流类的成员函数进行输入的函数。最后详细介绍了文件的 输入输出

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

    问题提出 最近工作中遇到这样一个需求:实现一个ToString函数将类型T转换到字符串,如果类型T中含有同名方法ToString...其中用到了一个C++17的std::void_t,考虑到目前C++17还没得用,这个实现只作参考之用(事实上C++

    回调成员函数,正则表达式,交互式调试模块

    模板类实现普通成员函数作为回调函数,deelx正则表达式库的使用示例,交互式控制台调试模块以及磁盘检测模块的封装类。转载请保留版权。

    c-c++及数据结构基础视频教程完整版,最适合自学的c++基础

    04_类中不写成员函数易犯错误模型 05-易犯错误模型-为什么需要成员函数(补充资料)-传智扫地僧 06_课堂答疑类中写成员函数_调用的时才会执行 07_程序设计方法发展历程 08_C语言和C++语言的关系_工作经验分享 09_...

    简单的C++串口示例

    使用编写的串口类文件,实现简单的C++串口通信MFC程序,可以实现可用串口检测,串口属性配置,开启关闭串口,通过回调函数将串口byte数据传递到其他类成员函数中使用

    传智播客_C++基础课程讲义_v1.0.7

    面试题4:是否可类的每个成员函数都声明为虚函数,为什么。 c++编译器多态实现原理 6 面试题5:构造函数中调用虚函数能实现多态吗?为什么? c++编译器多态实现原理 6 面试题6:虚函数表指针(VPTR)被编译器初始...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar

    谭浩强教授,我国著名计算机教育专家。1934年生。1958年清华大学毕业。学生时代曾担任清华大学学生会...8.3.2 在类外定义成员函数 8.3.3 inline成员函数 8.3.4 成员函数的存储方式 8.4 对象成员的引用 8.4.1 通过对象名...

    Visual C++2010开发权威指南(共三部分).part1.rar

    5.19.2 数值调节钮成员函数 251 5.20 Visual C++ 2010 GroupBox控件简介与开发 251 5.21 Visual C++ 2010 Data Time Picker控件简介与开发 252 5.21.1 创建日期和时间选择器控件 253 5.21.2 访问嵌入的月历控件 253 ...

    -C++参考大全(第四版) (2010 年度畅销榜

    23.4 const成员函数与mutable 23.5 volatile成员函数 23.6 explicit构造函数 23.7 成员初始化语法 23.8 利用关键字asm 23.9 连接说明 23.10 基于数组的I/O 23.11 C与C++的区别 第24章 标准模板库 24.1 STL概述 24.2 ...

    C++MFC教程

    在MFC中对消息的处理利用了消息映射的方法,该方法的基础是宏定义实现,通过宏定义将消息分派到不同的成员函数进行处理。下面简单讲述一下这种方法的实现方法: 代码如下 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd...

    C/C++程序员面试指南.杨国祥(带详细书签).pdf

    面试题7:C++的空类有哪些成员函数 8.3 构造函数和析构函数 面试题8:构造函数能否为虚函数 面试题9:简述子类与父类的析构、构造函数的调用顺序 面试题10:编写类String 的构造函数、析构函数和赋值函数 8.4 拷贝...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar )

    谭浩强教授,我国著名计算机教育专家。1934年生。1958年清华大学毕业。学生时代曾担任清华大学学生会...8.3.2 在类外定义成员函数 8.3.3 inline成员函数 8.3.4 成员函数的存储方式 8.4 对象成员的引用 8.4.1 通过对象名...

    C++编程思想(第2版 第2卷)

     1.5.4 函数级的try块   1.6 标准异常   1.7 异常规格说明   1.7.1 更好的异常规格说明   1.7.2 异常规格说明和继承   1.7.3 什么时候不使用异常规格说明   1.8 异常安全   1.9 在编程中使用...

    《Visual C++数字图像处理开发入门与编程实践》源码

    5.2.2 CBitmap中的成员函数 193 5.2.3 应用DDB显示图像 193 5.2.4 应用DDB显示大图像 195 5.3 进一步了解DIB 203 5.3.1 DIB的结构 203 5.3.2 DIB信息段 203 5.3.3 位图数据 205 5.3.4 与DIB有关的函数 206 5.4 本章...

    opencv3/C++ 实现SURF特征检测

    SURF即Speeded Up Robust Features加速鲁棒特征;...类SURF中成员函数create()参数说明: static Ptr&lt;SURF&gt; create( double hessianThreshold=100,//SURF中使用的hessian关键点检测器的阈值 int nOct

    c++实验报告(2).doc

    面向对象程序设计 (C++) 实 ... 构造函数是一种特殊的成员函数,与其他成员函数不同,不需要用户来调用它,而 是在建立对象时自动执行。 构造函数的名字必须与类名同名,而不能由用户任意命名,以便编译系统能识别它

    C++代码设计与重用

    3.4.7 妨碍继承的成员函数 3.5 派生赋值问题 3.6 允许入侵(用户修改源代码)继承 3.7 总结 3.8 练习 3.9 参考文献和相关资料 第4章 效率 4.1 效率和重用性 4.2 程序创建时间 4.2.1 编译时间 4.2.2 实例...

Global site tag (gtag.js) - Google Analytics