所以我有一个聚合类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)
,但我觉得这是重复的努力。有快速的方法吗?或者这种类型的构造函数不受欢迎?
答案 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的示例,了解更多详情。