C++无需std::mem_fn和lambda将成员函数指针转为普通函数指针的方案
解决方案
核心问题说明
你原有代码无法运行的根本原因是:this->*成员函数指针不是一个合法的可独立存在的表达式,该运算符仅可作为调用表达式的左操作数使用,必须紧跟参数列表(如(this->*ptr)(0))才符合语法规则,因此无法直接返回该表达式的结果。
无lambda的优雅实现方案
方案1:使用标准库std::bind(最推荐)
std::bind是C++标准库专门用于绑定可调用对象与参数的工具,完全不需要依赖lambda,可直接实现实例与成员函数的绑定,返回的可调用对象已内嵌当前Foo实例的信息,调用时无需再传入实例指针。
修正后的完整代码如下(将原有写死的int替换为模板参数T,适配不同的operator()实例化版本):
#include <functional> struct Foo { template <typename T> void operator()(T i) const { // 你的原有逻辑 } template <typename T> auto To() const { // 定义对应模板实例的成员函数指针类型 using MemFnType = void (Foo::*)(T) const; // 绑定当前实例this、成员函数,用占位符预留调用时的参数位置 return std::bind(static_cast<MemFnType>(&Foo::operator()), this, std::placeholders::_1); } };
使用示例:
int main() { Foo foo; auto callable = foo.To<int>(); callable(10); // 等价于 foo(10),无需额外传入foo实例 return 0; }
方案2:自定义轻量仿函数(如果你不想依赖std::bind)
你也可以手动实现嵌套仿函数来完成实例和成员函数的绑定,逻辑和std::bind的底层实现思路一致:
struct Foo { template <typename T> void operator()(T i) const { // 你的原有逻辑 } template <typename T> struct BoundCallable { const Foo* instance; using MemFnType = void (Foo::*)(T) const; MemFnType fn; void operator()(T val) const { (instance->*fn)(val); } }; template <typename T> auto To() const { using MemFnType = void (Foo::*)(T) const; return BoundCallable<T>{this, static_cast<MemFnType>(&Foo::operator())}; } };
该方案的使用方式和方案1完全一致,返回的BoundCallable对象同样内嵌了Foo实例指针,无需额外传参即可调用。
内容的提问来源于stack exchange,提问作者fdev
相关产品推荐
相关产品推荐

