12.8复制和移动类对象[class.copy]§31和§32说:
在具有类返回类型的函数的return语句中,当表达式是具有与函数返回类型相同的cv-unqualified类型的非易失性自动对象(函数或catch子句参数除外)的名称时,通过将自动对象直接构造到函数的返回值中,可以省略复制/移动操作
当满足或将满足复制操作的省略标准时,除了源对象是函数参数这一事实,并且要复制的对象由左值指定,重载决策选择复制的构造函数是首先执行,好像对象是由右值指定的.
因此我们可以写:
unique_ptr<int> make_answer()
{
unique_ptr<int> result(new int(42));
return result; // lvalue is implicitly treated as rvalue
}
Run Code Online (Sandbox Code Playgroud)
但是,我注意到g ++ 4.6.3也接受不是名称的左值,例如:
return (result);
return *&result;
return true ? result : result;
Run Code Online (Sandbox Code Playgroud)
相比之下,return rand() ? result : result;不起作用.编译器的优化器是否会干扰语言语义?当我解释标准时,return (result);不应该编译,因为(result)它不是名称,而是带括号的表达式.我是对还是错?
继我对此做出的评论之后:
将std :: vector传递给构造函数并移动语义
是否std::move在下面的代码中是必要的,以确保返回的值是xvalue?
std::vector<string> buildVector()
{
std::vector<string> local;
// .... build a vector
return std::move(local);
}
Run Code Online (Sandbox Code Playgroud)
我的理解是这是必需的.我经常看到std::unique_ptr从函数返回时使用的这个,但是GManNickG发表了以下评论:
我的理解是,在一个return语句中,所有局部变量都是自动xvalues(到期值)并将被移动,但我不确定它是否仅适用于返回的对象本身.所以OP应该继续把它放在那里,直到我更加自信它不应该是.:)
任何人都可以澄清是否std::move有必要吗?
行为编译器是否依赖?