C++如何实现向函数传递任意类的成员函数指针作为参数
实现支持任意类符合签名成员函数指针的方案
不同类的成员函数指针属于完全独立的类型,即使函数返回值、参数列表完全一致,也不存在通用的AllClassInstance类可以匹配所有类的成员函数指针,你可以选择以下两种常用方案实现需求:
方案1:模板方法实现(兼容C++03及以上旧标准)
将implfncptr改为模板方法,同时传入对应类的实例(成员函数调用必须绑定实例,这是C++语法强制要求,无法省略),实现代码如下:
修改后的fncptr2.h
#ifndef FNCPTR2 #define FNCPTR2 class fncptr2 { public: // 模板参数T匹配任意类类型 template<typename T> int implfncptr(T& instance, int (T::*func)(int, int)) { // 调用传入实例的对应成员函数 return (instance.*func)(1, 2); } }; #endif
调用示例(fncptr1.cpp中testfncptr修改)
void fncptr1::testfncptr() { fncptr2 f; // 传入当前类实例 + 成员函数指针即可 f.implfncptr(*this, &fncptr1::addition); }
该方案无需引入额外依赖,任意类只要存在返回int、带两个int参数的成员函数,都可以直接传入调用。
方案2:std::function实现(C++11及以上标准,更灵活)
如果你的项目支持C++11及更高版本,使用std::function可以完全解耦类型限制,除了成员函数外还支持普通函数、lambda、仿函数等所有符合int(int,int)签名的可调用对象:
修改后的fncptr2.h
#ifndef FNCPTR2 #define FNCPTR2 #include <functional> class fncptr2 { public: int implfncptr(std::function<int(int, int)> func) { return func(1, 2); } }; #endif
调用示例(fncptr1.cpp中testfncptr修改)
void fncptr1::testfncptr() { fncptr2 f; // 方式1:用std::bind绑定实例和成员函数 f.implfncptr(std::bind(&fncptr1::addition, this, std::placeholders::_1, std::placeholders::_2)); // 方式2:用lambda写法更直观 f.implfncptr([this](int a, int b) { return addition(a, b); }); }
内容的提问来源于stack exchange,提问作者sivanesan1
相关产品推荐
相关产品推荐

