Why is std::packaged_task not valid?

前端 未结 3 1813
北荒
北荒 2021-01-12 07:02

Using MSVC2012,

The following code will compile and run as expected

std::packaged_task< int() > task( []()->int{ std::cout << \"hello          


        
相关标签:
3条回答
  • 2021-01-12 07:25

    The problem is still there in MSVS 2013RC, but I made this temporary patch while MS corrects it. It is a specialization of packaged_task for void(...), so I suggest putting this in a header file and including it after the standard headers.Note that make_ready_at_thread_exit() is not implemented and some functions have not been fully tested, use at your own risk.

    namespace std {
    
    template<class... _ArgTypes>
    class packaged_task<void(_ArgTypes...)>
    {
        promise<void> _my_promise;
        function<void(_ArgTypes...)> _my_func;
    
    public:
        packaged_task() {
        }
    
        template<class _Fty2>
        explicit packaged_task(_Fty2&& _Fnarg)
          : _my_func(_Fnarg) {
        }
    
        packaged_task(packaged_task&& _Other)
          : _my_promise(move(_Other._my_promise)),
            _my_func(move(_Other._my_func)) {
        }
    
        packaged_task& operator=(packaged_task&& _Other) {
            _my_promise = move(_Other._my_promise);
            _my_func = move(_Other._my_func);
            return (*this);
        }
    
        packaged_task(const packaged_task&) = delete;
        packaged_task& operator=(const packaged_task&) = delete;
    
        ~packaged_task() {
        }
    
        void swap(packaged_task& _Other) {
            _my_promise.swap(_Other._my_promise);
            _my_func.swap(_Other._my_func);
        }
    
        explicit operator bool() const {
            return _my_func != false;
        }
    
        bool valid() const {
            return _my_func != false;
        }
    
        future<void> get_future() {
            return _my_promise.get_future();
        }
    
        void operator()(_ArgTypes... _Args) {
            _my_func(forward<_ArgTypes>(_Args)...);
            _my_promise.set_value();
        }
    
        void reset() {
            swap(packaged_task());
        }
    };
    
    }; // namespace std
    
    0 讨论(0)
  • 2021-01-12 07:33

    This is a bug in MSVC2012. There are quite a few bugs in the thread library implementation that ships with MSVC2012. I posted a partial list in my blog post comparing it to my commercial Just::Thread library: http://www.justsoftwaresolutions.co.uk/news/just-thread-v1.8.0-released.html

    0 讨论(0)
  • 2021-01-12 07:33

    This works in gcc 4.7.2:

    #include <thread>
    #include <future>
    #include <iostream>
    
    int main() {
      std::packaged_task< void() > task( [](){ std::cout << "hello world" << std::endl; } );
      std::thread t( std::move(task) );
      t.join();
      std::packaged_task< int() > task2( []()->int{ std::cout << "hello world" << std::endl; return 0; } );
      std::thread t2( std::move(task2) );
      t2.join();
    }  
    

    Together with @WhozCraig 's archeology implies that this is probably a bug in MSVC2012.

    For a workaround, try using struct Nothing {}; or nullptr_t as your return value?

    0 讨论(0)
提交回复
热议问题