Can't submit callble objects that return void to a thread pool, but only callable objects that returns values

♀尐吖头ヾ 提交于 2019-12-24 11:38:02

问题


I'm working on a thread pool from the book C++ Cuncerrency in Action by Anthony Willimas This thread pools has a submit call that take as tasks callable objects that return a value and return a std::future handle to them, and I managed to build applications that use it. But I can't manage to make it work with callable ojects that return void: the code won't even compile. I get these errors, all in the future header :

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    

The submit call is

    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;
    }

If I comment this line

work_queue.push(std::move(task));

the code compiles. So I think that the problem is "there"...

The work_queue is delcared as

threadsafe_queue<function_wrapper> work_queue;

where threadsafe_queue is

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();
    }

                 //[...]
}

and 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&);
};

I tried with, but I got the same errors.

    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;
    }

来源:https://stackoverflow.com/questions/20915316/cant-submit-callble-objects-that-return-void-to-a-thread-pool-but-only-callabl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!