c++ - 转发到 std::async
问题描述
这是我试图调用异步转发参数的(简化)代码:
template<typename Ret, typename ... Args>
class CallbackAsyncTask {
public:
CallbackAsyncTask() {
}
virtual ~CallbackAsyncTask() = default;
void execute( Args&& ... args ) {
execute(&CallbackAsyncTask<Ret, Args...>::onBackground, this, std::forward<Args>(args)...);
}
protected:
virtual Ret onBackground( Args& ... args ) = 0;
template<typename Fn, typename ... Argss>
void execute( Fn&& fn, Argss&& ... args ) noexcept(false) {
std::async(std::launch::async, std::forward<Fn>(fn), std::forward<Argss>(args)...);
}
};
class Child: public CallbackAsyncTask<int, int> {
public:
virtual int onBackground( int& i ) {
return i;
}
};
int main() {
Child c;
c.execute(15);
return 0;
}
我收到此错误:
../main.cpp: In instantiation of ‘void CallbackAsyncTask<Ret, Args>::execute(Fn&&, Argss&& ...) [with Fn = int (CallbackAsyncTask<int, int>::*)(int&); Argss = {CallbackAsyncTask<int, int>* const, int}; Ret = int; Args = {int}]’:
../main.cpp:27:98: required from ‘void CallbackAsyncTask<Ret, Args>::execute(Args&& ...) [with Ret = int; Args = {int}]’
../main.cpp:46:17: required from here
../main.cpp:33:90: error: no matching function for call to ‘async(std::launch, int (CallbackAsyncTask<int, int>::*)(int&), CallbackAsyncTask<int, int>* const, int)’
std::async(std::launch::async, std::forward<Fn>(fn), std::forward<Argss>(args)...);
^
../main.cpp:33:90: note: candidates are:
In file included from ../main.cpp:13:0:
/usr/include/c++/4.8.2/future:1532:5: note: template<class _Fn, class ... _Args> std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...)
async(launch __policy, _Fn&& __fn, _Args&&... __args)
^
/usr/include/c++/4.8.2/future:1532:5: note: template argument deduction/substitution failed:
/usr/include/c++/4.8.2/future: In substitution of ‘template<class _Fn, class ... _Args> std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(std::launch, _Fn&&, _Args&& ...) [with _Fn = int (CallbackAsyncTask<int, int>::*)(int&); _Args = {CallbackAsyncTask<int, int>* const, int}]’:
../main.cpp:33:90: required from ‘void CallbackAsyncTask<Ret, Args>::execute(Fn&&, Argss&& ...) [with Fn = int (CallbackAsyncTask<int, int>::*)(int&); Argss = {CallbackAsyncTask<int, int>* const, int}; Ret = int; Args = {int}]’
../main.cpp:27:98: required from ‘void CallbackAsyncTask<Ret, Args>::execute(Args&& ...) [with Ret = int; Args = {int}]’
../main.cpp:46:17: required from here
/usr/include/c++/4.8.2/future:1532:5: error: no type named ‘type’ in ‘class std::result_of<int (CallbackAsyncTask<int, int>::*(CallbackAsyncTask<int, int>*, int))(int&)>’
../main.cpp: In instantiation of ‘void CallbackAsyncTask<Ret, Args>::execute(Fn&&, Argss&& ...) [with Fn = int (CallbackAsyncTask<int, int>::*)(int&); Argss = {CallbackAsyncTask<int, int>* const, int}; Ret = int; Args = {int}]’:
../main.cpp:27:98: required from ‘void CallbackAsyncTask<Ret, Args>::execute(Args&& ...) [with Ret = int; Args = {int}]’
../main.cpp:46:17: required from here
/usr/include/c++/4.8.2/future:1552:5: note: template<class _Fn, class ... _Args> std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(_Fn&&, _Args&& ...)
async(_Fn&& __fn, _Args&&... __args)
^
/usr/include/c++/4.8.2/future:1552:5: note: template argument deduction/substitution failed:
/usr/include/c++/4.8.2/future: In substitution of ‘template<class _Fn, class ... _Args> std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(_Fn&&, _Args&& ...) [with _Fn = std::launch; _Args = {int (CallbackAsyncTask<int, int>::*)(int&), CallbackAsyncTask<int, int>* const, int}]’:
../main.cpp:33:90: required from ‘void CallbackAsyncTask<Ret, Args>::execute(Fn&&, Argss&& ...) [with Fn = int (CallbackAsyncTask<int, int>::*)(int&); Argss = {CallbackAsyncTask<int, int>* const, int}; Ret = int; Args = {int}]’
../main.cpp:27:98: required from ‘void CallbackAsyncTask<Ret, Args>::execute(Args&& ...) [with Ret = int; Args = {int}]’
../main.cpp:46:17: required from here
/usr/include/c++/4.8.2/future:1552:5: error: no type named ‘type’ in ‘class std::result_of<std::launch(int (CallbackAsyncTask<int, int>::*)(int&), CallbackAsyncTask<int, int>*, int)>’
我错过了什么?编译器GCC 4.8.3
解决方案
根本原因是这两行
virtual Ret onBackground( Args& ... args ) = 0;
virtual int onBackground( int& i )
启动任务时,参数要么直接转换,要么像std::thread
构造函数一样转换。在调用可调用对象时对decay_copy
参数执行此操作,因此非常量左值引用不能绑定到参数。
改变onBackground
接受参数的方式。例如,一个 const 左值引用有效。看直播。
推荐阅读
- c# - 如何在c#中将json格式字符串转换为json
- c# - 在 Monogame 中制作 Kitty Cannon,我如何将炮弹与其大炮对齐?
- python - 在python中将md5哈希转换为bigint
- python - 使用 Pandas 过滤基于列的特定信息
- java - 如何将字符串变量(s_code)传递给 Jsoup 伪选择器“:containsOwn(text)”而不是文本处的字符串值
- powershell - 如何从另一个 powershell 脚本执行 powershell 脚本,并具有等待和获取错误代码的能力?
- amazon-web-services - 如何使用颤振修复 AWS Cognito 上的注销错误?
- reactjs - ERR_EMPTY_RESPONSE 和 Uncaught (in promise) TypeError: Failed to fetch react.js express
- google-chrome - 将 chrome 背景颜色重置为默认值
- spring-webflux - Spring WebFlux Reactive MongoDB - 如何组合两个更改流?