没有编译带有packaged_task的模板
Template with packaged_task not compile
我正在玩Antony Williams - c++ Concurrency in Action一书中的一个示例4.14,其中使用std::packaged_task和std::thread模拟std::async。
为什么这段代码不编译时,我取消注释行和如何重写模板,使其工作?
#include <iostream>
#include <future>
#include <thread>
#include <string>
void func_string(const std::string &x) {}
void func_int(int x) {}
template <typename F, typename A>
std::future<typename std::result_of<F(A&&)>::type> spawn_task(F &&f, A &&a) {
typedef typename std::result_of<F(A&&)>::type result_type;
std::packaged_task<result_type(A&&)> task(std::move(f));
std::future<result_type> res(task.get_future());
std::thread t(std::move(task), std::move(a));
t.detach();
return res;
}
int main () {
std::string str = "abc";
// auto res1 = spawn_task(func_string, str);
// res1.get();
auto res2 = spawn_task(func_int, 10);
res2.get();
return 0;
}
编译错误:
nnovzver@archer /tmp $ clang++ -std=c++11 -lpthread temp.cpp && ./a.out
In file included from temp.cpp:2:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/future:38:
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/functional:1697:56: error: no type
named 'type' in 'std::result_of<std::packaged_task<void (std::basic_string<char> &)> (std::basic_string<char>)>'
typedef typename result_of<_Callable(_Args...)>::type result_type;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/thread:135:41: note: in instantiation
of template class 'std::_Bind_simple<std::packaged_task<void (std::basic_string<char> &)>
(std::basic_string<char>)>' requested here
_M_start_thread(_M_make_routine(std::__bind_simple(
^
temp.cpp:15:15: note: in instantiation of function template specialization 'std::thread::thread<std::packaged_task<void
(std::basic_string<char> &)>, std::basic_string<char> >' requested here
std::thread t(std::move(task), std::move(a));
^
temp.cpp:24:15: note: in instantiation of function template specialization 'spawn_task<void (&)(const
std::basic_string<char> &), std::basic_string<char> &>' requested here
auto res1 = spawn_task(func_string, str);
^
In file included from temp.cpp:2:
In file included from /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/future:38:
/usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../include/c++/4.8.2/functional:1726:50: error: no type
named 'type' in 'std::result_of<std::packaged_task<void (std::basic_string<char> &)> (std::basic_string<char>)>'
typename result_of<_Callable(_Args...)>::type
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
2 errors generated.
如果您查看async的文档,您想要模拟的特性,它会衰减所有未来的模板参数。它是有效的,因为它像这样工作得更好,如下所示:
template <typename T_>
using decay_t = typename std::decay<T_>::type;
template< class T >
using result_of_t = typename std::result_of<T>::type;
template <typename F, typename A>
std::future<result_of_t<decay_t<F>(decay_t<A>)>> spawn_task(F &&f, A &&a) {
using result_t = result_of_t<decay_t<F>(decay_t<A>)>;
std::packaged_task< result_t(decay_t<A>)> task(std::forward<F>(f));
auto res = task.get_future();
std::thread t(std::move(task), std::forward<A>(a));
t.detach();
return res;
}
首先,std::packaged_task
包装任何Callable目标函数。Callable的一个要求是它有一个合适的返回值。void
不是一个合适的返回值。我更改了您的函数以返回int
用于测试目的:
int func_string(const std::string &x)
{
return 1;
}
int func_int(int x)
{
return 2;
}
其次,在我看来,您的实际函数签名与您在std::result_of<>
模板中指定的内容之间存在不匹配。具体来说你的函数签名是:
int func_string(const std::string &x);
int func_int(int x);
但你正在通过:
std::result_of<F(A&&)>::type result_type
将其改为:
std::result_of<F(A)>::type result_type
一切都编译好了。
这是完整的源代码(减去头):
int func_string(const std::string &x)
{
return 1;
}
int func_int(int x)
{
return 2;
}
template <typename F, typename A>
std::future<typename std::result_of<F(A)>::type> spawn_task(F &&f, A &&a)
{
typedef typename std::result_of<F(A)>::type result_type;
std::packaged_task<result_type(A)> task(std::move(f));
std::future<result_type> res(task.get_future());
std::thread t(std::move(task), std::move(a));
t.detach();
return res;
}
int main()
{
std::string str = "abc";
auto res1 = spawn_task(func_string, str);
res1.get();
auto res2 = spawn_task(func_int, 10);
res2.get();
}
相关文章:
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 使用"Task"函数指针队列定义作业管理器
- Visual Studio C++ Project File CustomBuild Task: Filter Outp
- 如何将C std ::未来返回值调整到C#System.Threading.tasks.task
- C# Task.Run() vs. C++ std::async()
- C++ FOR LOOP ONLY task
- inline void addTask(Task task) vs inline void addTask(const Task &task)
- 为什么我会收到"variable 'std::packaged_task<int> task' has initializer but incomplete type"错误
- C++ -<Task> 删除堆上分配的任务数组时,将列表 l(或任何 STL 容器)添加为数据成员会导致错误
- "task"指令的"final"条款是否正确?
- 如何在后台进程上处理来自Windows任务管理器的"End Task"?
- 视觉工作室 2013 "A task was cancelled"
- 正在CDH4中获取mapreduce.task.partition
- 创建Task Then函数(类似std::future.then)
- 为什么不在pop之后运行task并返回true呢?
- Task of getline
- Tantamount of while(cin>>something){some task ;} in java?
- "typedef void (*task) ()"做什么?
- Glowcode内存使用量与Window Task Manager不同