为什么"std::async"没有按预期工作?
Why does "std::async" not work as expected?
#include <thread>
#include <functional>
#include <utility>
using namespace std;
template<typename Callable, typename... Args>
void Async(Callable&& fn, Args&&... args)
{
auto fn_wrapper = [](Callable&& fn, Args&&... args)
{
invoke(forward<Callable>(fn), forward<Args>(args)...);
};
// ok
fn_wrapper(forward<Callable>(fn), forward<Args>(args)...);
// ok
async(forward<Callable>(fn), forward<Args>(args)...);
// error : no matching function for call to 'async'
async(fn_wrapper, forward<Callable>(fn), forward<Args>(args)...);
}
void f(int, int) {}
int main()
{
Async(f, 1, 2);
this_thread::sleep_for(1min);
}
以下代码没问题:
fn_wrapper(forward<Callable>(fn), forward<Args>(args)...);
以下代码也可以:
async(forward<Callable>(fn), forward<Args>(args)...);
但是,以下代码是不行的:
// error : no matching function for call to 'async' async(fn_wrapper, forward<Callable>(fn), forward<Args>(args)...);
最后一种情况编译失败,并出现以下错误:
main.cpp:27:5: fatal error: no matching function for call to 'async'
async(fn_wrapper,
^~~~~
main.cpp:36:5: note: in instantiation of function template specialization 'Async<void (&)(int, int), int, int>' requested here
Async(f, 1, 2);
^
[...]
/usr/local/bin/../lib/gcc/x86_64-pc-linux-gnu/6.3.0/../../../../include/c++/6.3.0/future:1739:5: note: candidate template ignored: substitution failure [with _Fn = (lambda at main.cpp:12:9) &, _Args = <void (&)(int, int), int, int>]: no type named 'type' in 'std::result_of<(lambda at main.cpp:12:9) (void (*)(int, int), int, int)>'
async(_Fn&& __fn, _Args&&... __args)
为什么最后一个案例不起作用?
完美转发 ( &&
( 仅适用于模板参数上下文。但是您的 lambda 不是模板。因此,(Callable&& fn, Args&&... args)
只是在每个参数上打&&
,实际上意味着"通过右值引用传递",这不会正确地向前完善。
但更重要的是,std::async
将函子称为INVOKE(DECAY(std::forward<F>(f)), DECAY(std::forward<Args>(args))...)
,因此推导函子的参数类型实际上是衰减Callable
和Args
。
试试这个包装器:
auto fn_wrapper = [](auto&& fn, auto&&... args)
{
invoke(forward<decltype(fn)>(fn), forward<decltype(args)>(args)...);
};
相关文章:
- 为什么我的 std::ref 无法按预期工作?
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- std::unique_ptr 在 GCC 中工作,但不能在 Visual Studio 中编译
- 如何创建一个类,以便向量工作 std::vector<MyClass<int>> v{ 1,2,3 };
- std::数组边界检查如何工作?
- C++ assigment std::list:<typename>:itrator 在 main 中工作,但在方法中它不起作用
- std::strlen 在内部是如何工作的?
- std::async 如何工作:为什么它会调用这么多次复制/移动?
- std::bind,无法让具有单个参数的方法工作
- 为什么"std::is_function_v"不能按预期工作?
- 不使用与左右停止工作命名空间 std 的简单比较
- 对 std::vector 的这种解读是如何工作的?
- std::notify_all_at_thread_exit 如何工作?
- std::remove() 按预期处理文字,但不能与取消引用的迭代器一起工作
- ZeroMQ 在使用 std::thread 创建工作线程时崩溃
- 使用 std::atomic 标志和 std::condition_variable 在工作线程上等待
- 通过参数启用时,std::enabled_if 如何工作
- 双向链表 std::unique_ptr 类在节点删除时无法按预期工作
- pybind11:无法让 std::list 在 Python 中工作
- std:任何没有RTTI的,它是如何工作的