【发布时间】:2012-07-15 14:56:09
【问题描述】:
12.8 复制和移动类对象 [class.copy] §31 和 §32 说:
在具有类返回类型的函数的返回语句中,当表达式是具有相同的非易失性自动对象(函数或 catch 子句参数除外)的名称时 cv-unqualified类型作为函数返回类型,直接在函数返回值中构造自动对象即可省略复制/移动操作
当满足或将满足省略复制操作的条件时,除了源对象是函数参数的事实,并且要复制的对象由左值指定时,重载决策选择构造函数首先执行复制,就好像对象是由右值指定的一样。
因此我们可以这样写:
unique_ptr<int> make_answer()
{
unique_ptr<int> result(new int(42));
return result; // lvalue is implicitly treated as rvalue
}
但是,我注意到 g++ 4.6.3 也接受 不是名称 的左值,例如:
return (result);
return *&result;
return true ? result : result;
相比之下,return rand() ? result : result; 不起作用。编译器的优化器是否干扰了语言语义?在我解释标准时,return (result); 不应该编译,因为(result) 不是名称,而是带括号的表达式。我是对还是错?
【问题讨论】:
-
删除了ownership 标签,因为它只适用于特定示例,并且可以轻松更改为不涉及所有权的内容。,
-
引用最好保持其上下文部分完整,从“这种复制/移动操作的省略,称为复制省略,在以下情况下是允许的(可以组合以消除多个副本): " 或从段落的前一点开始。
-
我现在可以确认 VS2010 表现出相同的行为,在前两种情况下生成对移动构造函数的调用,但在第三种情况下抱怨无法访问复制 ctor。有趣的是,Intellisense 在第二种情况下已经抱怨应该调用复制 ctor 并且无法访问。 FWIW,GCC 4.7.1 传递所有 3。
标签: c++ c++11 return move-semantics