在C++中实现中的回调

Implementing a callback for in in C++?

本文关键字:回调 实现 C++      更新时间:2023-10-16

正如标题所要求的,我发现自己无法在C++中实现简单的(ha)回调函数。

现在,如果你在想"我确信我以前见过这个问题/答案",你是绝对正确的,即:c++中的回调函数

我重新发帖的原因是我什么都做不到。我已经尝试将我完全理解的第一个答案[1]直接应用到我的代码中;但我有30个错误。

这30个错误中的第一个问题,我不明白。它与typedef声明有关:

  typedef std::tr1::function<int (const GameCharacter&)> HealthCalcFunc;

似乎缺少"tr1":

....gLib..sor.h(47) : error C2039: 'function' : is not a member of 'std::tr1'

以下错误让人想起缺少";"丢失或类似:

....gLib..sor.h(47) : error C2143: syntax error : missing ';' before '<'
....gLib..sor.h(47) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
....gLib..sor.h(47) : error C2238: unexpected token(s) preceding ';'
....gLib..sor.h(51) : error C2061: syntax error : identifier 'DataProcessorFunc'
....gLib..sor.h(104) : error C2146: syntax error : missing ';' before identifier 'callbackFunc'

往下看,还有另一个答案[2],看起来更加明显。因此,我用这两个类创建了一个新的项目,但错误再次让我不知所措;我发现自己无法进步。

...gamecharactertestclass1.h(17) : error C2146: syntax error : missing ';' before identifier 'F1'
    ...gamecharactertestclass1.h(17) : error C2182: 'CALLBACK' : illegal use of type 'void'
jom:    ...GameCharacterTestMakefile.Release [releaseclass1.obj] Error 2
    ...gamecharactertestclass1.h(17) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    ...gamecharactertestclass1.h(17) : warning C4183: 'F1': missing return type; assumed to be a member function returning 'int'
    ...gamecharactertestclass1.h(19) : error C2143: syntax error : missing ':' before '}'
class1.cpp(11) : error C2143: syntax error : missing ';' before 'C1::F1'
class1.cpp(11) : error C2182: 'CALLBACK' : illegal use of type 'void'
class1.cpp(12) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    [...]
    ...gamecharactertestclass2.h(16) : error C2143: syntax error : missing ')' before '<tag>::*'
    ...gamecharactertestclass2.h(16) : error C2657: 'C1::*' found at the start of a statement (did you forget to specify a type?)
    ...gamecharactertestclass2.h(16) : error C2059: syntax error : ')'
    ...gamecharactertestclass2.h(16) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    ...gamecharactertestclass2.h(16) : warning C4183: 'pfnCallBack': missing return type; assumed to be a member function returning 'int'
    ...gamecharactertestclass2.h(21) : error C2061: syntax error : identifier 'pfnCallBack'
class2.cpp(10) : error C2061: syntax error : identifier 'pfnCallBack'
class2.cpp(14) : error C2065: 'pFn' : undeclared identifier

如果有人能好心地指出我哪里搞砸了,我将永远感激。非常感谢。

[1]https://stackoverflow.com/a/2298291/2903608

[2]https://stackoverflow.com/a/24899454/2903608

---------------------编辑--------------------

我已经修改了我的问题,我在回答这位天空之王的回答时补充了这一点。这很好,我想我只是在最后一关失败了。

我有一个头文件(class1.h)包含"class a",如他的回复所示:

#ifndef CLASS1_H
#define CLASS1_H
#include <QCoreApplication>
class A {
    void callback(int value) {
        printf("callback: got %dn", value);
    }
};
#endif // CLASS1_H

及其关联的(class1.cpp),包含其唯一的方法:

#include "class1.h"
void do_something(int value, A* obj, void (A::*cb)(int)) {
    (obj->*cb)(value);
}

在我的文件(主要是.cpp)中,我放置了函数定义和主要函数:

#include <QCoreApplication>
#include "class1.h"
using namespace std;
void callback(int value) {
     printf("callback: got %dn", value);
}
void do_something(int value, void (*cb)(int)) {
     // do something
     cb(value); // call the callback
}
void do_anotherthing(int value, std::function<void(int)> const& cb) {
    cb(value);
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    A theA = A();
    do_anotherthing(45, theA.callback);
    // Original exercise, works fine
    do_something(42, callback);
    return a.exec();
}

因此,当我执行第一步时,调用do_something(..),效果很好。但最后一步失败了。注意到,为了避免名称混淆,我将skyking对do_something()的最后两个定义重命名为do_anotherthing().。然而,我有以下错误,我不知道如何解决:

main.cpp(15) : error C2039: 'function' : is not a member of 'std'
main.cpp(15) : error C2061: syntax error : identifier 'function'
main.cpp(16) : error C3861: 'cb': identifier not found
main.cpp(24) : error C3867: 'A::callback': function call missing argument list; use '&A::callback' to create a pointer to member
main.cpp(24) : error C2660: 'do_anotherthing' : function does not take 2 arguments

最后,我只想花一点时间对我在SO需要发布问题时的知识和回复速度表示衷心的感谢。真的非常感谢大家。

我认为人们可能会质疑你完全理解答案的说法。

为了理解它,我认为你可能应该从问题的正确一端开始,去掉所有干扰核心问题的铃声和口哨声。让我们从一个简单的C-ish解决方案开始:

void callback(int value) {
     printf("callback: got %dn", value);
}
void do_something(int value, void (*cb)(int)) {
     // do something
     cb(value); // call the callback
}
int main() {
    do_something(42, callback);
    return 0;
}

没有什么奇怪的——回调只是指向随后调用的函数的指针。

下一步可能是观察如果您想将一个方法传递给do_something而不是普通函数会发生什么。它将失败,因为方法与函数的类型不同(因为它们不能以相同的方式使用,方法需要调用对象,而函数则不需要)。这意味着您必须使用指向(a)类成员的指针:

class A {
    void callback(int value) {
        printf("callback: got %dn", value);
    }
};
void do_something(int value, A* obj, void (A::*cb)(int)) {
    (obj->*cb)(value);
}

然而,这有一个问题,即您已经将自己限制为使用类A的方法作为回调——您不能再使用普通函数作为回调。这里std::function起到了拯救作用,因为它使用了一个包装器,可以在单个对象中包装任何类型的可调用对象

void do_something(int value, std::function<void(int)> const& cb) {
    cb(value);
}

然后你可以用任何类型的回调来调用它。