将rvalue引用传递给boost :: in_place函数

时间:2012-07-05 14:22:56

标签: c++ boost c++11 rvalue-reference

我是C ++中rvalue引用的新手,想要学习如何在日常生活中使用它们。 我有两个关于流行用例的连接问题:使用rvalue引用和boost :: in_place以及boost :: bind。

  1. 在boost :: in_place
  2. 中使用rvalue ref

    考虑一个类,构造函数将rvalue引用作为参数:

    struct A
        : boost::noncopyable 
    {
        A(int&&){}
    };
    

    现在让我们尝试为这个类创建boost可选变量:

    void foo(int&& value)
    {
        boost::optional<A> opt;
        // some code here 
        opt = boost::in_place(std::forward<int>(value)); //Error!
    }
    

    在这样的例子中传递rvalue ref的正确方法是什么。对于rvalue refs有没有像boost :: reference_wrapper这样的解决方案?

    1. 使用右值引用将绑定仿函数传递给函数对象
    2. 另一个常见的用例是将boost :: bind仿函数对象赋值给boost :: function对象。

      void foo(int&&)
      {
      }
      
      void bar()
      {
          boost::function<void(int&&)> func;
      
          int x = 0;
          func = boost::bind(foo, std::move(x)); // Compilation error (a)
      
          func = boost::bind(foo, _1); // Compilation error too (b)
      }
      

      我理解指令(a)可能在第一次调用后导致未定义的变量值,但指令(b)甚至没有这样的问题。但是如何正确编写这段代码呢?

1 个答案:

答案 0 :(得分:0)

boost in_places本身不支持移动或r值引用。但是,您可以创建一个继承自boost :: in_place_factory_base的新类,并创建自己的类。或者您可以使用支持emplace函数的可选项(如folly :: Optional)。

我不确定我是否建议这样做,但你可以在boost中设置一个通用的重载来处理它,如下所示:

#include <boost/optional.hpp>      
#include <boost/utility/in_place_factory.hpp>
#include <folly/ApplyTuple.h>

namespace boost                                                                      
{                                                                                  
  template<class ... As> 
  struct rvalue_in_place : public in_place_factory_base 
  {
    mutable std::tuple<As...> tup_; 
    rvalue_in_place(As ... as)
      : tup_(std::forward<As>(as)...)
   {
   }                                                                                   
   template< class T >
   void apply ( void* address ) const 
   {
     auto make = [address](As ... as) { new (address) T(std::forward<As>(as)...);  }; 
     folly::applyTuple(make, tup_); 
   }
 };   
 template <class ... As> 
 rvalue_in_place<As&&...> in_place(As && ... a)
 {
   return rvalue_in_place<As&&...>(std::forward<As>(a)...);
 }
}