11
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超出范围时,数据“3”应该被删除。但是代码如何在没有任何访问冲突的情况下工作?

4

2 回答 2

15

这在 C++11 标准第 12.8/32 节中有规定:

当满足或将满足复制操作的省略标准时,除了源对象是函数参数的事实,并且要复制的对象由左值指定时,选择复制的构造函数的重载决策是首先执行好像对象是由右值指定的......

(强调我的)。用简单的英语来说,这意味着当涉及到重载决议时,左值p可以被视为一个rvalue,因为它是复制省略的候选者。这反过来意味着移动构造函数在重载决议时被拾取(实际上,移动副本可能无论如何都被省略了。)

于 2014-09-17T07:58:16.453 回答
6

由于return某些表达式(例如局部自动变量)被明确定义为返回移动的对象,如果移动运算符可用的话。

所以:

return p;

或多或少类似于:

return std::move(p);

但请注意,这不适用于例如全局变量。

std::unique_ptr<int> g(new int(3));
std::unique_ptr<int> ptr() {
    return g;  //  error!!!
}
于 2014-09-17T07:56:25.970 回答