C++ 处理嵌套回调

C++ 处理嵌套回调,c++,function,c++11,callback,C++,Function,C++11,Callback,我遇到了一个需要处理嵌套回调的案例。请参阅Thing::process函数。第二个g\u thing.onAfterWalk()回调永远不会被调用,因为父回调在执行完成后会立即销毁它 Thing g_thing; void Thing::walk(int32_t x, int32_t y) { if (SYSTIME() > m_walkEndTime) { // Still walking return; } auto obj

我遇到了一个需要处理嵌套回调的案例。请参阅
Thing::process
函数。第二个
g\u thing.onAfterWalk()
回调永远不会被调用,因为父回调在执行完成后会立即销毁它

Thing g_thing;

void Thing::walk(int32_t x, int32_t y) {
    if (SYSTIME() > m_walkEndTime) {
        // Still walking
        return;
    }

    auto obj = g_thing.localObject();
    auto walkDuration = obj->getWalkDurationTo(x, y);
    [..]
    m_walkEndTime = SYSTIME() + walkDuration;

    [..]

    // Walk finished. Run callback
    if (m_afterWalk) {
        m_afterWalk();
        m_afterWalk = nullptr;
    }
}

void Thing::onAfterWalk(std::function<void(void)>& callback) {
    m_afterWalk = callback;
}

void Thing::process() {
    [..]
    // Store a callback and walk
    g_thing.onAfterWalk([]() {
        // Store another callback
        // After walking to 4321, 4321 do something else.
        // My actual problem... Callback within callback
        g_thing.onAfterWalk([]() { 
            std::cout << "Walking finished.\n";
        });

        // After walking to 1234, 1234 walk to 4321, 4321
        g_thing.walk(4321, 4321);
    });
    g_thing.walk(1234, 1234);
}
thingg_;
虚无之物::行走(int32_t x,int32_t y){
如果(SYSTIME()>m_walkEndTime){
//还在走
返回;
}
auto obj=g_thing.localObject();
自动walkDuration=obj->getWalkDurationTo(x,y);
[..]
m_walkEndTime=SYSTIME()+行走持续时间;
[..]
//步行结束。运行回调
if(m_后行走){
m_后走();
m_后走=空PTR;
}
}
void Thing::onAfterWalk(std::函数和回调){
m_后走=回叫;
}
void Thing::process(){
[..]
//存储回调并步行
g_thing.onAfterWalk([](){
//存储另一个回调
//走到4321后,4321做点别的。
//我的实际问题…回调中的回调
g_thing.onAfterWalk([](){
std::cout对我很有效(有一些调整:
const
在参数上设置为
onAfterWalk
,最后设置为
std::cout.flush()

#include <iostream>
#include <functional>

class Thing;
extern Thing g_thing;

class Thing
{
  std::function<void(void)> m_afterWalk;
public:
  void walk()
  {
    if(m_afterWalk)
    {
      m_afterWalk();
      m_afterWalk = nullptr;
    }
  }

  void onAfterWalk(const std::function<void(void)>& callback)
  {
    m_afterWalk = callback;
  }

  void process()
  {
    // Store a callback and walk
    g_thing.onAfterWalk([]() {
        // Store another callback
        g_thing.onAfterWalk([]() {
            std::cout << "Walking finished.\n";
        });
        g_thing.walk();
    });
    g_thing.walk();
  }
};

Thing g_thing;

int main(int argc, char *argv[])
{
  g_thing.process();
  std::cout.flush();
}

所以,散步之后,您希望再次调用
walk
?基本上,我希望在到达第一个位置后
walk
到另一个位置。您不应该在散步之前设置onAfterWalk回调吗?(在这两种情况下?)@lockcmpxchg8b观点很好。你说得对。我会改变这一点。我认为问题仍然是一样的。我认为这会解决你的问题。在第一次步行后,你将完成第二次步行,然后第一次步行将回调指针设置为Null。我认为这对你有效,因为你会立即运行两次回调。试着用一点时间调用每一次有点延迟。请参阅。时间不会影响这一点(没有其他线程)。在您的新链接中,我看到您使用了一些新函数,例如
g_thing.localObject();
,这些函数在任何地方都没有定义。如果您在省略的部分([…])中开始任何其他行走那么这种方法肯定行不通。我可能会建议粘贴有问题的整个代码,或者澄清您想要答案的问题。任何其他行走都不会开始。唯一的用法是问题中显示的这两个。其余部分只涉及每一步更新对象位置,这就是我跳过的原因t、 我会继续挖掘,因为看起来我遗漏了什么。嗯。在你对StoryTeller的回复中,你声明
walk
不会被阻止。你能在你的问题中详细说明一下吗?这可能会改变我对w.r.t线程的假设。就像在我的pastebin代码片段中一样-
walk
方法在实际行走之前返回已完成。它确实设置了时间以及目标位置并返回。StoryTeller实现需要在方法返回后执行行走。
$ g++ -pedantic -Wall -Werror test.cpp
$ ./a.out
Walking finished.