简体   繁体   English

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

[英]Implementing a callback for in in C++?

As the title asks, I find myself unable to implement a straightforward (ha) callback function in C++. 正如标题所要求的,我发现自己无法在C ++中实现简单的(ha)回调函数。

Now if you're thinking "I'm sure I've seen a question/answer for that before", you're absolutely correct, namely: Callback functions in c++ 现在,如果您在考虑“我肯定之前已经看过一个问题/答案”,那么您绝对正确,即: c ++中的回调函数

The reason I am posting anew is that I cannot get anything to work. 我要重新发布的原因是我什么都无法工作。 I've tried applying the 1st answer that I fully understand [1], directly to my code; 我尝试将我完全理解的第一个答案[1]直接应用于我的代码; but I get 30 errors. 但我得到30个错误。

The first problem of these 30 errors, I don't understand. 我不理解这30个错误中的第一个问题。 It's relating to the typedef declaration: 它与typedef声明有关:

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

It appears that 'tr1' is missing: 似乎缺少“ tr1”:

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

The following errors are reminiscent of a missing ';' 以下错误让人想起缺少的“;” gone missing or similar: 丢失或类似:

..\..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'

Moving down the page, there is another answer [2] that appears even more obvious. 向下移动页面,还有另一个答案[2]显得更加明显。 So I've created a fresh project with these two classes but again the errors beat me; 因此,我使用这两个类创建了一个新项目,但是错误再次使我失望; I find myself unable to progress. 我发现自己无法进步。

...\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

If someone could be so kind as to point out where I have screwed up, I would be eternally grateful. 如果有人能指出我在哪里搞砸了,我将永远感激不已。 Many thanks in advance. 提前谢谢了。

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

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

--------------------- Edit -------------------- ---------------------编辑--------------------

I have amended my question and I'm adding this in reply to this skyking's reply. 我已经修正了我的问题,并添加了此内容以回应这一天才的答复。 It's very good, I think I'm just failing at the final hurdle though. 很好,我想我只是在最后的关口失败了。

I have a header file (class1.h) containing "class A" as illustrated in his reply: 我有一个头文件(class1.h),其中包含“ A类”,如他的回复所示:

#ifndef CLASS1_H
#define CLASS1_H

#include <QCoreApplication>

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

and its associated (class1.cpp) containing its sole method: 及其关联的(class1.cpp)包含其唯一方法:

#include "class1.h"

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

and in my file (mainly.cpp) I've placed the function definitions and the main function: 在我的文件(主要是.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();
}

So when I do the initial step, calling do_something(..) that works fine. 因此,当我执行初始步骤时,调用do_something(..)可以正常工作。 But the final step fails. 但是最后一步失败了。 Noted that to avoid confusions over names, I have renamed skyking's two last definition of do_something() to be called to do_anotherthing(). 注意,为避免名称混淆,我将重命名了skyking的do_something()最后两个定义,称为do_anotherthing(). However, I have the following errors which I don't know how to sort out: 但是,我有以下错误,我不知道如何解决:

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

Finally, I would just like to take a moment to express my immense gratitude for the knowledge and speed of the replies on the occasions I needed to post a question here at SO. 最后,我想花一点时间对我在SO提出问题的场合的答复的知识和速度表示由衷的感谢。 Thank you all very much indeed. 的确非常感谢大家。

I think one could question the claim that you fully understand the answer(s). 我认为有人可能会质疑您完全理解答案的说法。

To get an understanding of it I think you should probably start in the right end of the problem by cutting away all the bells-and-whistles that distracts from the core issue. 为了理解它,我认为您可能应该从消除问题的正确开始入手,以消除所有分散核心问题的烦恼。 Let's start with a plain C-ish solution: 让我们从一个简单的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;
}

nothing fancy - the callback is simply a pointer to a function that is then called. 没什么花哨的-回调只是指向随后被调用的函数的指针。

Next step is maybe to watch what happens if you want to pass a method to do_something instead of a plain vanilla function. 下一步可能是观察如果您想将方法传递给do_something而不是普通的香草函数,将会发生什么。 It will fail because a method is not of the same type as a function (because they cannot be used the same way, a method needs an object to be called while a function doesn't). 它将失败,因为方法与函数的类型不同(因为不能以相同的方式使用它们,因此方法需要调用一个对象,而函数则不需要)。 This means that you would have to use a pointer to member of (a) class instead: 这意味着您将不得不使用指向(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);
}

However this has the problem that you have restricted youself to having a method of class A as the callback - you couldn't no longer use a plain function as callback. 但是,这有一个问题,您将自己限制为使用A类的方法作为回调-您不能再将纯函数用作回调。 Here std::function comes to the rescue since it uses a wrapper that can wrap any kind of callables in a single object 这里的std::function可以解决,因为它使用了可以将任何类型的可调用对象包装在单个对象中的包装器

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

then you can call it with any kind of callbacks. 那么您可以通过任何类型的回调对其进行调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM