(新增C++)保存稍后可以调用的函数指针

(New to C++) Save a function pointer that can be called later

本文关键字:调用 函数 指针 C++ 新增 保存      更新时间:2023-10-16

我花了一些时间试图弄清楚如何做到这一点,但我认为我需要帮助。如果我可以使用模板,我可以避免输入函数,例如"B::theFuncToBeCalled",对吧?但这只有在它是静态方法时才有效,如果我没记错的话?

// A.h
typedef std::function <void()> CbType;
class A
{
template<typename T>
void setCallback(T &cb);
private:
template <typename T>
T callThisLater;
};
// A.cpp
template<typename T>
void A::setCallback(T &cb)
{
this->callThisLater = cb;
// later...
((CbType*)callThisLater)();
}
// B.cpp
// in constructor or wherever
{
A* a;
a->setCallback(this->theFuncToBeCalled);
// or, anonymous
CbType func = [this](){
// do something
// call theFuncToBeCalled() if I feel like it :)
};
a->setCallback(func);
}
void B::theFuncToBeCalled()
{
log("yay");
}

(如果我尝试以匿名方式执行此操作,则会收到访问冲突错误。

这里有很多错误。让我们讨论一下,然后如何解决它:

  1. 您不能简单地在实现文件中定义模板化函数:https://isocpp.org/wiki/faq/templates#templates-defn-vs-decl
  2. C++14 的变量模板仅适用于静态变量:
变量

模板定义一系列变量或静态数据成员

  1. 您正在传递一个方法,并尝试像传递函数一样使用它,方法隐式采用this参数
  2. 一旦将callThisLater类型定义为接受方法,就无法随后将其更改为接受具有不同签名的 lambda
  3. class A是用函子甚至只是函数指针可以解决的问题的糟糕重新实现

请简单地消除class A并使用函数指针和闭包类型:

auto a = &B::theFuncToBeCalled;
auto func = [=]() { (*this.*a)(); }

与其使用a继续前进,不如使用func

我决定改变我的方法,而不是保存指向回调的指针,而是保存指向成员函数所属对象的指针。这是相同的工作量,但好处是,如果我需要调用几个不同的成员函数,我可以只做:

objRef->theFuncToBeCalled();
// later
objRef->theOtherFuncToBeCalled();

而我所需要的,只是一个指针。简单是最好的™,对吧?:)感谢您的帮助!