首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将未来转化为lambda表达式

如何将未来转化为lambda表达式
EN

Stack Overflow用户
提问于 2016-06-14 10:35:43
回答 1查看 1.6K关注 0票数 6

我正在使用Visual 2013,我希望实现这一行代码

代码语言:javascript
复制
 f = p.get_future();
 auto task =[f = std::move(f)](){
   //use f
 };

我知道解决方案这里,但不幸的是这不能在VS2013 (error C2558 no copy-constructor available)下编译。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-14 13:50:41

您可以使用shared_future。这是最简单的。

然而,这并不能帮你移动。如果您确实需要移动,我们可以借助move_helper函数和类来完成:

代码语言:javascript
复制
template<class T, class F=void>
struct move_helper_t {
  T t;
  F f;
  template<class...Args>
  auto operator()(Args&&...args)
  ->typename std::result_of< F&(T&, Args...) >::type
  {
    return f(t, std::forward<Args>(args)...);
  }

  // force right-associativity of `->*`, and
  // invert the stack to get the arguments in the "right" order:
  template<class F1,
    class R0=move_helper_t< T, typename std::decay<F1>::type >
  >
  auto operator->*(F1&& f1)
  -> decltype(
    std::declval<F>()->*
    std::declval<R0>()
  )
  {
    return
      std::move(f)->*
      R0{ std::forward<T>(t), std::forward<F1>(f1) };
  }
};
template<class T>
struct move_helper_t<T,void> {
  T t;
  template<class F>
  auto operator->*(F&& f)
  -> move_helper_t<T, typename std::decay<F>::type>
  {
    return {std::forward<T>(t), std::forward<F>(f)};
  }
};

template<class T>
move_helper_t<std::decay_t<T>>
move_helper( T&& t ) {
  return {std::forward<T>(t)};
}

在2013年MSVC中,您可能必须在move_helper_t中声明构造函数。我不记得他们的return {}代码写得有多好。

代码语言:javascript
复制
f = p.get_future();
task =
  move_helper(std::move(f)) ->*
  [](std::future<int>& f){
    //use f
  };

->*move_helper绑定到lambda。然后,它返回一个可调用对象,该对象将作为调用时的第一个参数传递给std::future<int>&

由于它是如何编写的,您甚至可以将其链接起来:

代码语言:javascript
复制
auto f = p.get_future();
auto f2 = p2.get_future();
task =
  move_helper(std::move(f)) ->*
  move_helper(std::move(f2)) ->*
  [](std::future<int>& f, std::future<char>& f2){
    //use f
  };

把一个以上的论点移到兰博达。

在这两种情况下,task都可以由task()调用-- ->*操作将lambda绑定起来,并在调用时传递期货。

实例化

请注意,这解决了将未来迁移到lambda中的问题。如果要将lambda存储在std::function中,这将无助于您,因为函数必须是可复制的。

代码语言:javascript
复制
template<class F>
struct shared_function {
  std::shared_ptr<F> pf;
  template<class ...Args>
  typename std::result_of<F&(Args...)>::type
  operator()(Args&&...args) const {
   return (*pf)(std::forward<Args>(args)...);
  }
};
template<class F,
  class dF=typename std::decay<F>::type
>
shared_function< dF >
make_shared_function( F&& f ) {
  return {std::make_shared<dF>(std::forward<F>(f))};
}

这需要一个可移动的lambda,并将其封装在一个共享指针中,并为您公开operator()。但是,首先将future通过上述技术将其移动到lambda中,然后在共享函数中包装该lambda以将其传递给std::function,这是很荒谬的:首先使用shared_future

顺便提一下,理论上,packaged_task只需要移动,但我不确定MSVC2013是否支持该要求。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37809571

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档