【问题标题】:passing rvalue reference into boost::in_place function将右值引用传递给 boost::in_place 函数
【发布时间】:2012-07-05 23:24:15
【问题描述】:

我是 C++ 中右值引用的新手,想了解如何在日常生活中使用它们。 我有 2 个关于流行用例的相关问题:使用带有 boost::in_place 和 boost::bind 的右值引用。

  1. 在 boost::in_place 中使用右值引用

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

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

在这样的示例中,传递右值 ref 的正确方法是什么。 rvalue refs 是否有类似 boost::reference_wrapper 的解决方案?

  1. 将绑定函子传递给具有右值引用的函数对象

另一个常见的用例是将 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) 甚至没有这样的问题。但是如何正确编写这段代码呢?

【问题讨论】:

  • 我不建议将 C++11 功能与为不了解 C++11 的 C++03 编写的库一起使用。检查文档以查看是否支持此类用法,据我所知,对于 Boost.Optional 和 Boost.Function 而言,这不是。
  • Boost 库通常使用新标准的新功能(即使没有 C++11,只有 C++0x)。我已经使用 C++11 中的新本机“绑定”和“函数”检查了第二个示例 - 效果相同(无法检查第一个示例,因为 C++11 中没有“可选”)。

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


【解决方案1】:

boost in_places 本身不支持移动或右值引用。但是,您可以创建一个继承自 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)...);
 }
}

【讨论】:

  • 谢谢,@capsterx。我已经为 boost::in_place 找到了patch,它适用于右值。同时有承诺会增加这个功能来提升发布boost tracker
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-09-09
  • 1970-01-01
  • 2018-09-09
  • 1970-01-01
  • 2014-02-22
  • 1970-01-01
相关资源
最近更新 更多