Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost equivalent of std::async()

Without using boost::thread and boost::bind directly, is there a way to implement the equivalent of the following code?

std::string func()
{
    std::string str("Hello from async task!");
    return str;
}

int main()
{
    auto ftr = std::async(&func);
    std::cout << "Hello from main!";
    std::string str = ftr.get();
    std::cout << str << std::endl;      
    return 0;
}

Specifically, this part: auto ftr = std::async(&func); ?

like image 536
Pat Mustard Avatar asked Jan 16 '12 06:01

Pat Mustard


1 Answers

Certainly. Simply make async<T>(std::function<T()>) return a future which invokes func() the moment it's first waited-for. You won't get any asynchronicity, but the API doesn't actually guarantee that the function will run asynchronously, so that's not a problem.

If you have access to an OS-specific threading library, you could of course use that as well.

Note, however, that storing exceptions cannot be implemented portably; it requires additional support from the C++ implementation, unless you can restrict the exceptions supported to ones with a polymorphic clone function. See this question for more information.

The final implementation might look a bit like this (untested):

// NOTE - we assume a SINGLE THREADED environment

template<typename T>
class myfuture_detail {
    mutable boost::variant<T, boost::function<T()> > val;

public:
    myfuture_detail(const boost::function<T()> &f)
        : val(f) { }

    const T &get() const {
        if (T *t = boost::get<T>(&val)) {
            return *t;
        } else {
            boost::function<T()> f = *boost::get<boost::function<T> >(&val);
            val = f();

            T *t = boost::get<T>(&val);
            assert(t);

            return *t;
        }
    }
};

template<typename T>
class myfuture {
    boost::shared_ptr<myfuture_detail<T> > ptr;

public:
    myfuture(const boost::function<T()> &f)
        : ptr(boost::make_shared<myfuture_detail<T> >(f))
    {}

    myfuture() { }

    const T &get() const {
        return ptr->get();
    }
};
like image 109
bdonlan Avatar answered Sep 21 '22 10:09

bdonlan