`
tcspecial
  • 浏览: 914082 次
  • 性别: 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++函数参考手册C++专业

    1. **标准库函数**:C++标准库提供了许多函数,如`std::vector`的成员函数(如`push_back`、`pop_back`)用于向动态数组添加或移除元素,`std::string`的成员函数(如`substr`、`append`)处理字符串操作,以及`std:...

    C++检测网络连接是否正常

    网络连接的检测通常涉及到TCP或UDP协议的使用,这两个协议是Internet协议族中的主要成员。在这个项目中,可能会使用到以下知识点: 1. **套接字编程**:C++Builder集成了 Indy 库,这是一个强大的套接字库,可以...

    c++的文件操作函数详解

    打开文件时通常使用`open()`成员函数,该函数原型如下: ```cpp void open(const char* filename, int mode, int access = 0); ``` - **参数**: - `filename`: 指定要打开的文件名。 - `mode`: 文件打开模式,可...

    c++磁盘检测

    4. **友元函数或静态成员函数**:为了封装上述的系统调用,可能需要定义一些友元函数或静态成员函数,这些函数负责实际的系统交互,然后将结果传递给类的成员变量。 5. **输出函数**:例如`printInfo()`,用于打印...

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

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

    C++宏跟函数及常量基础学习

    - 类中的成员函数默认为内联,非类函数可通过`inline`关键字声明为内联。 4. **常量**: - `const`常量提供类型安全,如`const int bufsize = 100;`,编译器可以检测常量的类型和使用。 - 宏定义的常量无类型...

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

    在IT领域,回调成员函数、正则表达式、交互式调试模块和磁盘检测是重要的技术概念,它们在软件开发中扮演着关键角色。让我们详细探讨这些知识点。 首先,回调成员函数是一种编程技术,允许将类的某个成员函数作为...

    pclint c++ 语法语意检测

    2. **使用const以表明不变性**:PCLint可以识别那些本应声明为const但未声明的成员函数和变量,以防止意外修改。 3. **避免隐式类型转换**:PCLint检查可能的隐式类型转换,防止潜在的类型安全问题。 4. **明智地...

    交换函数_c++交换函数_

    此外,自定义的`swap`函数也可以被`std::swap`模板调用,因为C++标准库提供了对用户自定义类型的自动检测和支持。 交换函数在实际编程中有着广泛的应用。例如,在STL(Standard Template Library,标准模板库)的...

    C++ 检测计算机信息

    例如,可以创建`SystemInfo`类,包含`getOsInfo`、`getCpuInfo`、`getMemoryInfo`和`getNetworkInfo`等成员函数,方便地集成到你的项目中。 总之,C++检测计算机信息是一个综合性的任务,涉及多个层面的知识,包括...

    visual c++ vc检测U盘的插入,拔出.并获取U盘对应的盘符.zip

    `DetectUSBDlg.cpp`包含了类的成员函数实现,而`DetectUSBDlg.h`则定义了类的结构和成员函数声明。 3. `DetectUSB.cpp` 和 `DetectUSB.h`:这两个文件定义和实现了主程序类`DetectUSB`。`DetectUSB.cpp`包含处理USB...

    C++I/O描述

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

    OpenCV实现亚像素级角点检测(C++实现).zip

    开发者可以通过构造对象,调用成员函数来执行角点检测。 4. **OpenCV工程环境**:为了使项目能够顺利编译和运行,需要配置正确的OpenCV开发环境。这通常包括安装OpenCV库,设置编译器的链接器选项,以及确保包含...

    C++ 面试题精选

    本文档总结了C++中的重要知识点,涵盖了构造函数、虚函数、静态成员、重载、重写、成员函数、全局函数、友元函数、继承、面向对象特点、常引用和断言等方面的知识。 1. 构造函数不能声明为虚函数的原因:因为虚函数...

    C++ 读取硬盘序列号、驱动类型、卷标等

    类的成员函数可能包括: 1. `GetSerialNumber()`:用于读取硬盘序列号。这可能涉及到调用`DeviceIoControl`函数,传递特定的控制代码(如`IOCTL_STORAGE_QUERY_PROPERTY`)和参数,以获取硬盘的物理属性。 2. `...

    C++模板函数重载规则详解

    这个类使用SFINAE(Substitution Failure Is Not An Error)原则来检测类型是否具有特定的成员函数。`HasToString`的工作原理是通过模板特化和模板参数推断来实现的,虽然初看复杂,但其本质是在编译期间生成不同的...

    C++库函数查询手册

    `any(bitset)`函数是C++标准库中bitset的一个成员函数,用于检查bitset中是否存在至少一个被设置为1的位。如果存在,则返回true;否则返回false。这对于快速判断bitset状态非常有用,尤其是在处理二进制数据或进行位...

    浙江大学《C++》九套期末模式复习题(含答案).pdf

    在C++中,使用输入输出流类的成员函数可以检测流的状态。只有输入流(如istream类)具有特定的成员函数(如fail())来检测输入流是否失败。而对于输出流(如ostream类),通常使用bad()来检测流是否出现错误。 11. ...

    VC++ 检测键盘任意按键是否按下并跟踪显示键值

    如果使用`MFC`,则可以创建一个`CWinApp`或`CDialog`派生类,并重写`OnKeyDown`和`OnKeyUp`成员函数来处理键盘事件: ```cpp void CMyApp::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { // nChar包含了按...

Global site tag (gtag.js) - Google Analytics