【问题标题】:Generic Callback通用回调
【发布时间】:2012-06-07 03:28:07
【问题描述】:

我正在尝试将回调存储在一个类中。目前,我做这样的事情:

struct Callback {
    Callback (std::function<void ()> func) : func_ (func){}
    void call() const { func(); }

private:
    std::function<void ()> func_;
};

如您所见,只能使用特定类型的函数(目前没有返回和无参数)。

有什么方法可以使用这样的类,我可以通过它来调用它吗?

void increment (int &n) {
    ++n;
}

int main() {
    int someNum = 5;
    Callback callback (increment, someNum); //will call `increment (someNum);`
}

我正在考虑使用参数包来存储参数,并使用typename 来存储返回类型,然后制作std::function&lt;ReturnType (Args)&gt; callback_ 之类的东西,并用callback_ (givenArgs...); 之类的东西调用它。但是,我对模板的了解还不够,甚至无法确定是否可行。

我将摆脱它的真正用途(至少现在)是用于计时器,但也许制作一个包装 std::function&lt;&gt; 的小型 generic_function&lt;&gt; 类会有所帮助。然而,对于这个例子,一个每 2 秒暂停和取消暂停的计时器:

void togglePause (Countdown &c) {
    c.togglePause();
}

int main() {
    Countdown main (10000); //create countdown of 10s
    Countdown delay (2000, togglePause, main); //this one calls func when expired

    for (; !main.expired();) { //go while unpaused time < 10s
        delay.wait().reset(); //wait 2s, call callback, reset back to 2s
    }
}

当然,这也可以应用于其他概念,但我不确定如何首先获得这种语法。如果返回类型为void,我可以构建两种不同的形式,这与之前无关的问题无关,但是存储具有任意数量和类型的参数的函数会让我感到困惑。如果可能的话,我该如何使用这样的语法?如果不是,语法有多接近?

【问题讨论】:

  • 我一直在走这条路,虽然不是使用 C++11(实际上这应该会让它更加更容易)。注意invisible calling conventions
  • @Cameron,感谢您的提醒。我将不得不提防这一点,因为我无疑会在未来使用 winapi 函数尝试此操作并感到非常困惑。
  • 你的平台是什么? (MSVC++?GCC?x86 还是 x64?)
  • 查看我的更新答案:我错过了 std::ref

标签: c++ templates generics callback c++11


【解决方案1】:

我认为您只想使用 std::bind 将带参数的函数转换为不带参数的函数:

int main() {
    int someNum = 5;
    std::function<void (void)> boundFunc = std::bind(increment, std::ref(someNum));
    Callback callback (boundFunc); //will call `increment (someNum);`
}

请注意,您需要 std::ref 以确保 someNum 通过引用传递,并且您需要确保 someNum 在范围内的停留时间比回调长。

【讨论】:

  • 看起来它应该可以工作(很好的想法),但不幸的是它没有。不过,可能是我。查看我更新的问题。
  • 是的,当我看到它时,我大声地呻吟着。它与测试用例完美配合,所以我可以假设在我实现它时它会。非常感谢。这比我想象的要简单得多。我总是设法找到最乏味的做事方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-22
  • 2013-12-01
  • 2021-05-25
  • 2017-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多