使用 std::bind 将 QTimer::singleShot 传递给 std::async

Pass QTimer::singleShot to std::async using std::bind

以下代码启动一个非阻塞计时器,该计时器将在一秒后启动函数 myFunc

MyClass.h:

std::future<void> timer_future_;

MyClass.cpp:

timer_future_ = std::async(

        std::launch::async,
        [this] { QTimer::singleShot(1000,
                                    [this] {this->myFunc();}
                                    );
               }
    );

我想用 std::functions 替换 lambda 函数。我已经成功替换了第二个 lambda,如下所示:

timer_future_ = std::async(

        std::launch::async,
        [this] { QTimer::singleShot(1000, 
                                    std::bind(&MyClass::myFunc, this)
                                    );
               }
    );

现在如何用另一个 std::bind() 调用替换第一个 lambda?

请注意,函数 QTimer::singleShot 来自 Qt 库;它的文档是 here。它的原型是:

void QTimer::singleShot(int msec, Functor functor)

根据 this question, the definition of the Functor type can be found in QObject.h。它说:

template <class FunctorT, class R, typename... Args> class Functor { /*...*/ }

经过一些研究,我了解到将替换第一个 lambda 的 std::bind() 必须考虑以下因素:

我试过几次都不成功,最后一次是:

timer_future_ = std::async(
        std::launch::async,
        std::bind( ( void(*) (int, Functor<const std::function<void(void)>,void>) )&QTimer::singleShot,
                  1000,
                  std::bind(&MyClass::myFunc, this)
                  )
);

对于这段代码,MSVC 编译器返回了错误信息

error: C2059: syntax error: ')'

在第三行。

为什么我不直接使用已经工作的 lambda 表达式? 答案很简单,尝试使用 std::bind() 反而让我学到了更多关于C++语言的各种特性以及如何使用它们。


编辑: 实现 Kuba Ober 答案的代码:

QTimer::singleShot(1000, [this] {
    timer_future_ = std::async(
                std::launch::async,
                std::bind(&MyClass::myFunc, this)
                );
});

计算左括号和右括号并添加分号

计时器需要一个事件循环,std::async 将在没有 运行ning 事件循环的工作线程中调用它。我怀疑你为什么要这样做?

如果您想 运行 延迟后在工作线程中执行某些操作,运行 具有事件循环的线程中的计时器,并从该计时器触发异步操作。