Увеличить эквивалент std :: async () - PullRequest
10 голосов
/ 16 января 2012

Без непосредственного использования boost::thread и boost::bind, есть ли способ реализовать эквивалент следующего кода?

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

В частности, эта часть: auto ftr = std::async(&func);?

1 Ответ

9 голосов
/ 16 января 2012

Конечно. Просто заставьте async<T>(std::function<T()>) вернуть будущее, которое вызывает func() в тот момент, когда его впервые ждут. Вы не получите никакой асинхронности, но API фактически не гарантирует, что функция будет работать асинхронно, так что это не проблема.

Если у вас есть доступ к библиотеке потоков, специфичной для ОС, вы, конечно, можете использовать и ее.

Обратите внимание, однако, что сохранение исключений не может быть реализовано переносимым образом; это требует дополнительной поддержки от реализации C ++, если только вы не можете ограничить поддерживаемые исключения теми, у которых есть функция полиморфного клона. См. этот вопрос для получения дополнительной информации.

Окончательная реализация может выглядеть примерно так (не проверено):

// 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();
    }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...