std::unique_ptr<int> ptr() {
std::unique_ptr<int> p(new int(3));
return p; // Why doesn't this require explicit move using std::move?
} // Why didn't the data pointed to by 'p' is not destroyed here though p is not moved?
int main() {
std::unique_ptr<int> a = ptr(); // Why doesn't this require std::move?
std::cout << *a; // Prints 3.
}
在上面的代码中,函数ptr()
返回p
的副本。当p
超出范围时,数据&#39; 3&#39}应该被删除。但是代码如何在没有任何访问冲突的情况下工作?
答案 0 :(得分:14)
这是在C ++ 11标准中提出的,§12.8/ 32 :
当符合或将要执行复制操作的标准时 因为源对象是一个函数参数这个事实, 并且要复制的对象由左值重载指定 首先执行选择复制的构造函数的分辨率 好像对象是由右值指定的 ....
(强调我的)。用简单的英语表示,当涉及到重载决策时,左值p
可以被视为rvalue
,因为它是 copy elision 的候选者。这反过来意味着移动构造函数在重载决策时被拾取(事实上,移动副本可能无论如何都会被删除。)
答案 1 :(得分:6)
因为某些表达式的return
(例如本地自动变量)被明确定义为返回移动的对象,因此移动运算符可用。< / p>
所以:
return p;
或多或少类似于:
return std::move(p);
但请注意,这不适用于全局变量。
std::unique_ptr<int> g(new int(3));
std::unique_ptr<int> ptr() {
return g; // error!!!
}