Конечно. Просто заставьте 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();
}
};