在C ++中实现in的回调?

时间:2015-10-26 12:09:44

标签: c++

正如标题所示,我发现自己无法在C ++中实现直接(ha)回调函数。

现在,如果您正在考虑“我确定之前我已经看到了问题/答案”,那么您绝对正确,即:Callback functions in 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]显得更加明显。所以我用这两个类创建了一个新项目,但错误再一次打败了我;我发现自己无法进步。

...\gamecharactertest\class1.h(17) : error C2146: syntax error : missing ';' before identifier 'F1'
    ...\gamecharactertest\class1.h(17) : error C2182: 'CALLBACK' : illegal use of type 'void'
jom:    ...\GameCharacterTest\Makefile.Release [release\class1.obj] Error 2
    ...\gamecharactertest\class1.h(17) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    ...\gamecharactertest\class1.h(17) : warning C4183: 'F1': missing return type; assumed to be a member function returning 'int'
    ...\gamecharactertest\class1.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
    [...]
    ...\gamecharactertest\class2.h(16) : error C2143: syntax error : missing ')' before '<tag>::*'
    ...\gamecharactertest\class2.h(16) : error C2657: 'C1::*' found at the start of a statement (did you forget to specify a type?)
    ...\gamecharactertest\class2.h(16) : error C2059: syntax error : ')'
    ...\gamecharactertest\class2.h(16) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    ...\gamecharactertest\class2.h(16) : warning C4183: 'pfnCallBack': missing return type; assumed to be a member function returning 'int'
    ...\gamecharactertest\class2.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

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

我已经修改了我的问题,我在回复此skyking的回复时添加了这个问题。这非常好,我想我只是在最后的障碍中失败了。

我有一个包含“A类”的头文件(class1.h),如他的回复所示:

#ifndef CLASS1_H
#define CLASS1_H

#include <QCoreApplication>

class A {
    void callback(int value) {
        printf("callback: got %d\n", value);
    }
};
#endif // CLASS1_H

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

#include "class1.h"

void do_something(int value, A* obj, void (A::*cb)(int)) {
    (obj->*cb)(value);
}

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

#include <QCoreApplication>
#include "class1.h"

using namespace std;

void callback(int value) {
     printf("callback: got %d\n", 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(..)可以正常工作。但最后一步失败了。请注意,为避免混淆名称,我已将天空的最后一个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上发布问题的时候回复的知识和速度表示非常感谢。非常感谢你们。

1 个答案:

答案 0 :(得分:5)

我认为可以质疑你完全理解答案的说法。

为了理解它,我认为你应该从问题的正确开始,切掉所有分散核心问题的钟声和口哨声。让我们从一个简单的C-ish解决方案开始:

void callback(int value) {
     printf("callback: got %d\n", 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而不是普通的vanilla函数会发生什么。它将失败,因为方法与函数的类型不同(因为它们不能以相同的方式使用,方法需要在函数不调用时调用对象)。这意味着您必须使用指向(a)类成员的指针:

class A {
    void callback(int value) {
        printf("callback: got %d\n", value);
    }
};

void do_something(int value, A* obj, void (A::*cb)(int)) {
    (obj->*cb)(value);
}

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

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

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