【问题标题】:Obtaining a function pointer to a non static member function获取指向非静态成员函数的函数指针
【发布时间】:2020-12-11 02:29:25
【问题描述】:

假设我有一堂课:

class A {
public:
    A(); 
    void myFunc();
};

然后在程序的不同点创建一个类 A 的实例,并尝试获取指向 myFunc() 的函数指针:

A* a = new A;

//ATTEMPTS AT RETRIVING FUNCTION POINTER FOR A::MYFUNC

std::function<void()> fnptr = a->myFunc;

std::function<void()> fnptr(std::bind(A::myFunc, &a);

但是这两种尝试都会出现错误“调用没有对象参数的非静态成员函数”

也许这两种尝试都完全不合时宜,但实际上我试图在a 的特定实例中获取指向myFunc() 函数的函数指针。任何有关如何做到这一点的帮助表示赞赏:)

【问题讨论】:

  • std::bind(A::myFunc, &amp;a a 已经是一个指针。不需要另一个级别的间接。看看Lambda Expressions 作为bind 的更有效替代方案
  • std::function&lt;void()&gt; fnptr = [a]{ a-&gt;myFunc(); };

标签: c++ function-pointers member-function-pointers


【解决方案1】:

我正在尝试获取指向myFunc() 函数的函数指针

可以获取指向A::myFunc()的成员函数的指针:

void (A::*memFuncPtr)() = &A::myFunc;

甚至更好,利用auto:

auto memFuncPtr = &A::myFunc;

但是,要取消引用此指针(即调用它指向的成员函数),您最终将需要一个 A 对象。此对象对应于将调用成员函数的对象。

您可以取消引用指向成员函数 memFuncPtr 的指针,或者与 A 对象和 .* 运算符结合使用:

A a;
a.*memFuncPtr();

或与指向A 对象的指针和运算符-&gt;* 结合使用:

A *aPtr = new A();
aPtr->*memFuncPtr();

因此,您需要保留对对象的引用或对象的副本,以便使用此指向成员函数的指针创建 std::function&lt;void()&gt;

std::invoke

从 C++17 开始,您可以简单地使用 std::invoke() 函数模板来代替 .* / -&gt;*。它统一了上面公开的两种情况的语法:

std::invoke(memFuncPtr, a);
std::invoke(memFuncPtr, aPtr);

【讨论】:

  • 在处理原始函数指针时进一步阅读更多技巧和工具:Pointers to Member Functions
  • @user4581301 感谢您的链接。我扩展了介绍std::invoke的答案。
【解决方案2】:

您需要以下语法:

std::function<void()> fnptr(std::bind(&A::myFunc, a));

你也可以像这样使用 lambda 表达式:

auto fn = [a] { a->myFunc(); };

这是demo

【讨论】:

  • 非常感谢,lambda 是一个完美的实现。也许只是一个跟进:如果我想将该函数指针传递给函数fnPtrHandlerfnPtrHandler 的原型会是什么样子?
  • 如果你想把它传递给一个函数,那么签名就是void f(void (A::*)());。当然,您可以传递 std::function&lt;void()&gt; 或将 f 设为模板。
猜你喜欢
  • 2010-11-02
  • 2018-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-28
  • 1970-01-01
相关资源
最近更新 更多