2012-01-16 75 views
9

如果不直接使用boost::threadboost::bind,有没有一种方法可以实现以下代码的等效功能?等效于std :: async()的提升

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

回答

8

当然。只需让async<T>(std::function<T()>)返回一个未来,在第一次等待时调用func()。您不会获得任何异步性,但API实际上并不保证该函数将异步运行,所以这不是问题。

如果您有权访问特定于操作系统的线程库,那么您当然也可以使用它。

但是,请注意,存储异常不能移植;它需要来自C++实现的额外支持,除非可以将支持的异常限制为具有多态克隆函数的异常。有关更多信息,请参阅this question

最终实施可能看起来有点像这样(未经):

// 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(); 
    } 
}; 
+0

感谢您的详细答复!对于元编程,我是一个新手,所以我不确定如何以与OP中的示例相同的方式使用它...例如,在哪里将相当于'std :: async( )'进入它? 'myfuture'类是否需要以某种方式绑定到'boost :: thread'? – 2012-01-16 07:29:22

+1

这实际上并不是异步的。 'std :: async'的合约实际上并不保证异步例程将异步运行。考虑是否在到达'.get()'之前,异步线程永远不会被调度 - 它实际上是同步的。这是我在这里完成的 - 因为你没有线程,我只是假装它是异步运行的,只是在你找到结果之前碰巧没有做任何事情。 – bdonlan 2012-01-16 15:33:59

+0

“*但是请注意,存储异常不能被移植实现*”不[Boost.Exception](http://www.boost.org/libs/exception/)是否可以执行此操作? – ildjarn 2012-01-24 18:37:01