无法向线程池提交返回void的callble对象,但只能提交返回值的可调用对象

时间:2014-01-04 00:41:03

标签: c++ multithreading c++11 threadpool std

我正在从书中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;
    }

0 个答案:

没有答案