1

I'm trying to get the code from this post to work with Visual Studio 2013. My current version is below and works fine with gcc and clang (coliru demo).

The standard says about std::async in 30.6.8.2:

Requires: F and each Ti in Args shall satisfy the MoveConstructible requirements.

But the standard library from MSVC seems to try to copy the functor object, which will obviously not work because of the std::future member.

My current workaround is the commented out copy constructor that does evil stuff, but maybe a reference object would be a better workaround.

Is my code incorrect or does VS have a bug there? Is there a better workaround if this is a bug?

#ifndef CONTINUATION_H
#define CONTINUATION_H

#include <future>


namespace detail {

    template<typename F, typename W, typename R>
    struct helper
    {
        F f;
        W w;

        helper(F f, W w)
            : f(std::move(f))
            , w(std::move(w))
        {
        }

        /*helper(const helper& other)
            : f(std::move(const_cast<helper&>(other).f))
            , w(other.w)
        {
        }*/

        helper(helper&& other)
            : f(std::move(other.f))
            , w(std::move(other.w))
        {
        }

        helper& operator=(helper other)
        {
            f = std::move(other.f);
            w = std::move(other.w);
            return *this;
        }

        R operator()()
        {
            f.wait();
            return w(std::move(f));
        }
    };

}

namespace util
{
    template<typename F, typename W>
    auto then(F f, W w) -> std::future<decltype(w(std::move(f)))>
    {
        return std::async(std::launch::async, detail::helper<F, W, decltype(w(std::move(f)))>(std::move(f), std::move(w)));
    }
}

#endif



int main()
{
    std::promise<int> prom;
    auto fut = prom.get_future();

    std::thread th([&](){
        prom.set_value(42);
    });

    util::then(std::move(fut), [](std::future<int> f){
        printf("future got: %i\n", f.get());
    });

    th.join();
}
Community
  • 1
  • 1
typ1232
  • 5,535
  • 6
  • 35
  • 51
  • Looks like [this bug](https://connect.microsoft.com/VisualStudio/feedback/details/800833/std-async-does-not-work-properly-with-movable-types). Can't think of any workarounds though. – Praetorian Jul 22 '14 at 20:18
  • As far as I can tell it's a bug, I've run into it multiple times. The best workaround I can think of is passing by std::shared_ptr. – axnsan Jul 22 '14 at 20:19

0 Answers0