以下编译没有错误:
#include <memory>
std::unique_ptr<int> f() {
std::unique_ptr<int> x(new int(42));
return x;
}
int main() {
std::unique_ptr<int> y = f();
}
Run Code Online (Sandbox Code Playgroud)
我认为返回值是f()由复制初始化的x,但是std::unique_ptr是一个只移动的类型.怎么这不是格式错误,因为复制构造函数不可用?标准中的相关条款是什么?是否存在某个地方,表示if f()是仅移动类型而不是return语句变为移动构造而不是复制构造?
And*_*owl 16
我认为返回值是
f()由复制初始化的x,但是std::unique_ptr是一个只移动的类型
返回值f()确实是从表达式中复制初始化的x,但复制初始化并不总是意味着复制构造.如果表达式是rvalue,则移位构造函数将被重载决策选中(假设存在移动构造函数).
现在,虽然这是事实,表达x的return x;语句,其中还附有自动存储持续时间命名对象的左值(这可能会导致您认为我只是写不适用),在的情况下,编译器将首先尝试将id-expression视为重载解析的右值.
标准中的相关条款是什么?是否存在某个地方,表明如果
f()是仅移动类型而不是return语句变为移动构造而不是复制构造?
根据C++标准的第12.8/32段([class.copy]/32,草案N4296):
当满足复制/移动操作的省略标准时,但不满足异常声明,并且要复制的对象由左值指定,或者当
return语句中的表达式是(可能带括号的)id表达式时命名具有在最内层封闭函数或lambda-expression 的body或parameter-declaration-clause中声明的自动存储持续时间的对象,首先执行用于选择复制的构造函数的重载决策,就好像该对象由rvalue指定一样.[...]