唯一指针:LValue Reference与RValue Reference函数调用



我开始使用c++std::unique_ptrs,偶然发现了以下问题:

我想将唯一指针的引用传递给函数,并为此函数中的指针分配一个新值。直观地说,我认为函数需要引用lvalue才能修改指针。但是,在下面的代码示例中,两个选项(lvalue引用和rvalue引用+std::move(的作用相同(我想(。

#include <memory>
#include <utility>
struct Widget {
Widget(int) {}
};
void reseat_RValue(std::unique_ptr<Widget>&& uniqPtr) {
auto tempUniqPtr = std::make_unique<Widget>(2003);
uniqPtr = std::move(tempUniqPtr);
}
void reseat_LValue(std::unique_ptr<Widget>& uniqPtr) {
auto tempUniqPtr = std::make_unique<Widget>(2010);
uniqPtr = std::move(tempUniqPtr);
}
int main() {
auto uniqPtr = std::make_unique<Widget>(1998);
reseat_RValue(std::move(uniqPtr)); // (1)
reseat_LValue(uniqPtr); // (2)   
}

我真的不明白,(1)(2)之间有什么区别,或者更确切地说,我应该在我的用例中使用哪一个。所以也许有人可以解释一下这些函数中的每一个是怎么回事,以及我应该使用哪一个。

是的,他们也做同样的事情。从您的意图来看,即通过引用传递并在函数中修改它,通过左值引用传递会更好。它让你的意图更加清晰(正如@bitmask所建议的那样(;函数需要一个左值,并会在函数内部对其进行修改。对于通过右值引用传递,需要使用std::move将左值传递给函数,并且它允许像临时值一样传递右值,这似乎毫无意义。例如

// meaningless; the temporary `std::unique_ptr` would be destroyed immediately
reseat_RValue(std::make_unique<Widget>(1998)); 

实际上,std::unique_ptr::reset在具有左值引用的函数中为您做了同样的事情——它更简单。IMO,右值语义最适合大型对象,而不是指针。但是,unique_ptr使用它来实现唯一的指针计数。

最新更新