使用默认和移动构造函数的类Widget
,我想编写一个函数:
Widget
类型的左值作为参数,Widget
实例。例如:
Widget w;
auto p1 = pointer_from_lrvalue(Widget()); // rvalue argument
auto p2 = pointer_from_lrvalue(w); // lvalue argument
// w is guaranteed to be no longer used from now on
pointer_from_lrvalue()
可能如下所示:
std::unique_ptr<Widget> pointer_from_lrvalue(Widget w) {
return std::unique_ptr<Widget>(new Widget(std::move(w)));
}
这样的路过价值方法在他的scopeGuard()
函数[ErrorHandling-slides,第48页]中显示了Andrei Alexandrescu。但是,这种方法的缺点是,在传递左值参数Widget
时,需要w
的复制构造函数(至少使用g ++ 4.9.2)。 / p>
我能够找到以下解决方案以防止调用/需要复制构造函数。第一个使用左值和右值引用:
std::unique_ptr<Widget> pointer_from_lrvalue(Widget& w) {
return std::unique_ptr<Widget>(new Widget(std::move(w)));
}
std::unique_ptr<Widget> pointer_from_lrvalue(Widget&& w) {
return std::unique_ptr<Widget>(new Widget(std::move(w)));
}
第二个使用通用引用:
template <typename T>
std::unique_ptr<std::remove_reference_t<T>> pointer_from_lrvalue(T&& t) {
return std::unique_ptr<std::remove_reference_t<T>>
(new std::remove_reference_t<T>(std::move(t)));
}
我想知道:
Widget
复制构造函数?答案 0 :(得分:4)
是的,他们都是正确的,并保证只会调用移动。
这是相当主观的。我个人更喜欢转发参考,因为我讨厌代码重复。但是,它确实需要将代码放在标题中。
如果您想要开心,可以创建自己的非模板&#34;移动Widget
参考:&#34;
class WidgetMover
{
Widget& widget;
public:
Widget&& moveWidget() { return std::move(widget); }
WidgetMover(Widget &w) : widget(w) {}
WidgetMover(Widget &&w) : widget(w) {}
};
std::unique_ptr<Widget> pointer_from_lrvalue(WidgetMover w) {
return std::unique_ptr<Widget>(new Widget(w.moveWidget()));
}
必须注意确保没有WidgetMover
超过其初始化的右值的生命周期。