我正在从书中C++ Cuncerrency in Action by Anthony Willimas开发一个线程池
这个线程池有一个提交调用,它作为任务返回一个值的可调用对象并返回一个std::future
句柄,我设法构建使用它的应用程序。
但是我无法设法使用可返回void的可调用对象:代码甚至无法编译。我在future
标题中收到了这些错误:
error C2182: '_Get_value' : illegal use of type 'void'
error C2182: '_Val' : illegal use of type 'void'
error C2182: '_Val' : illegal use of type 'void'
error C2665: 'std::forward' : none of the 2 overloads could convert all the argument types
error C2512: 'std::_Promise<int>' : no appropriate default constructor available
submit
来电是
template<typename FunctionType>
std::future<typename std::result_of<FunctionType()>::type> submit(FunctionType f){
typedef typename std::result_of<FunctionType()>::type result_type;
std::packaged_task<result_type()> task(std::move(f));
std::future<result_type> res(task.get_future());
work_queue.push(std::move(task));
return res;
}
如果我评论这一行
work_queue.push(std::move(task));
代码编译。所以我认为问题是“那里”......
work_queue
被视为
threadsafe_queue<function_wrapper> work_queue;
其中threadsafe_queue
是
template<typename T>
class threadsafe_queue{
private:
mutable std::mutex mut;
std::queue<std::shared_ptr<T> > data_queue;
std::condition_variable data_cond;
public:
threadsafe_queue(){}
void push(T new_value){
std::shared_ptr<T> data(
std::make_shared<T>(std::move(new_value)));
std::lock_guard<std::mutex> lk(mut);
data_queue.push(data);
data_cond.notify_one();
}
//[...]
}
和threadsafe_queue
class function_wrapper{
struct impl_base {
virtual void call()=0;
virtual ~impl_base() {}
};
std::unique_ptr<impl_base> impl;
template<typename F>
struct impl_type: impl_base{
F f;
impl_type(F&& f_): f(std::move(f_)) {}
void call() { f(); }
};
public:
template<typename F>
function_wrapper(F&& f):impl(new impl_type<F>(std::move(f))){}
void operator()() { impl->call(); }
function_wrapper(){}
function_wrapper(function_wrapper&& other):impl(std::move(other.impl)){}
function_wrapper& operator=(function_wrapper&& other){
impl=std::move(other.impl);
return *this;
}
private:
function_wrapper(const function_wrapper&);
function_wrapper(function_wrapper&);
function_wrapper& operator=(const function_wrapper&);
};
我试过了,但我也遇到了同样的错误。
template<typename FunctionType>
std::future<void> submit(FunctionType f){
std::packaged_task<void(void)> task(std::move(f));
std::future<void> res(task.get_future());
work_queue.push(std::move(task));
return res;
}