置换可移动结构

时间:2013-10-22 13:22:32

标签: c++ c++11 move-semantics

所以我有一个聚合类Foo,它采用可移动和(间接)可复制的参数(一个名为Image_t的类,一个std::unique_ptr<Map>,而Map可以克隆自己。)

我希望为最终用户提供创建课程的灵活性。所以我有一个“类似副本”的构造函数和一个“类似移动”的构造函数:

  typdef std::unique_ptr<Map> MapPtr;

  ///
  ///@brief Copy build constructor
  ///
  Foo(const Image_t& image, const MapPtr& map_ptr) :
  image_(image),
  geo_locatormap_(map_ptr->clone())
  {

  }

  ///
  ///@brief Move build constructor
  ///
  Foo(Image_t&& image, MapPtr&& map_ptr) :
  image_(std::move(image))
  geo_locatormap_(std::move(map_ptr))
  {

  }

理想情况下,我也想拥有Foo(const Image_t& image, MapPtr&& map_ptr)Foo(Image_t&& image, const MapPtr& map_ptr),但我觉得这是重复的努力。有快速的方法吗?或者这种类型的构造函数不受欢迎?

3 个答案:

答案 0 :(得分:3)

使用类型扣除,完美转发和小帮手:

static MapPtr&& map_forward( MapPtr&& m ) { return std::move( m ); }
static MapPtr map_forward( const MapPtr& m ) { return m->clone(); }

template<typename I, typename M>
Foo(I&& i, M&& m) :
image_{std::forward<I>(i)},
geo_locatormap_{map_forward(std::forward<M>(m))}
{

}

答案 1 :(得分:1)

在你的情况下,因为你不能完全转发map_ptr通过(除非你使用像Daniel Frey的答案那样的帮助函数),你需要单独处理这个案例。我可以想到将构造函数减少到两个的一种方法是这样的:

// Clone the map.
template <typename Image>
Foo(Image&& img, MapPtr const& map_ptr)
    : image_{ std::forward<Image>(img) },
      geo_locatormap_{ map_ptr->clone() }
{ }

// move the map.
template <typename Image>
Foo(Image&& img, MapPtr&& map_ptr)
    : image_{ std::forward<Image>(img) },
      geo_locatormap_{ std::move(map_ptr) }
{ }

The Image&amp;&amp;语法将绑定到任何左值/右值引用,使用std::forward,您将获得该类型的最佳操作。

答案 2 :(得分:0)

仅定义一个版本就足够了: Foo(Image_t&& image, MapPtr&& map_ptr)

请查看this link的示例,了解更多详情。