The following code starts a non-blocking timer that will launch the function myFunc
after one second:
MyClass.h:
std::future<void> timer_future_;
MyClass.cpp:
timer_future_ = std::async(
std::launch::async,
[this] { QTimer::singleShot(1000,
[this] {this->myFunc();}
);
}
);
I would like to replace the lambda functions with std::function
s. I have successfully replaced the second lambda as follows:
timer_future_ = std::async(
std::launch::async,
[this] { QTimer::singleShot(1000,
std::bind(&MyClass::myFunc, this)
);
}
);
How can I now replace the first lambda with another std::bind()
call?
Note that the function QTimer::singleShot
is from the Qt libraries; its documentation is here. Its prototype is:
void QTimer::singleShot(int msec, Functor functor)
As per this question, the definition of the Functor type can be found in QObject.h
. It says:
template <class FunctorT, class R, typename... Args> class Functor { /*...*/ }
After some research, I understand that the std::bind()
that will replace the first lambda must take account of the following:
QTimer::singleShot
is an overloaded function, so I must use a cast to disambiguate the call to itQTimer::singleShot
is a static member function, so the pointer to it must resemble a pointer to a non-member functionI have made several unsuccessful attempts, the last of which was:
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)
)
);
For this code, the MSVC compiler returned the error message
error: C2059: syntax error: ')'
on the third line.
Why don’t I just use the lambdas which are already working? The answer is simply that trying to use std::bind() instead is teaching me more about the various features of the C++ language and how to use them.
EDIT: Code that implements Kuba Ober's answer:
QTimer::singleShot(1000, [this] {
timer_future_ = std::async(
std::launch::async,
std::bind(&MyClass::myFunc, this)
);
});
The timer requires an event loop, and std::async
will invoke it in a worker thread that doesn't have a running event loop. I question why would you ever want to do it?
If you want to run something in a worker thread after a delay, run the timer in a thread that has an event loop, and fire off the async action from that timer.