问题描述
12.8复制和移动类对象[class.copy]§31和§32说:
12.8 Copying and moving class objects [class.copy] §31 and §32 say:
当满足或将要满足复制操作的省略标准时,除非源对象是函数参数,并且要复制的对象由左值指定,否则重载分辨率以选择用于首先执行复制操作,就好像该对象是由右值指定的.
When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue.
因此我们可以写:
unique_ptr<int> make_answer()
{
unique_ptr<int> result(new int(42));
return result; // lvalue is implicitly treated as rvalue
}
但是,我注意到g ++ 4.6.3还接受不是名称的左值,例如:
However, I noticed that g++ 4.6.3 also accepts lvalues that are not names, for example:
return (result);
return *&result;
return true ? result : result;
相比之下,return rand() ? result : result;
不起作用.编译器的优化器是否在干扰语言语义?在解释标准时,return (result);
不应编译,因为(result)
不是名称,而是带括号的表达式.我是对还是错?
By contrast, return rand() ? result : result;
does not work. Is the compiler's optimizer interfering with the language semantics? As I interpret the standard, return (result);
should not compile, because (result)
is not a name, but a parenthesized expression. Am I right or wrong?
推荐答案
关于带括号的表达式 [√]
在谈论带括号的表达式时,您错了,并且返回 且仅包含名称时,它不应触发 move 可移动对象.
Regarding parenthesized expressions [√]
You are wrong when talking about parenthesized expressions and that it shouldn't be able to trigger a move when being returned and containing only the name of a moveable object.
关于constexpr 条件运算符 [╳]
Regarding the constexpr conditional operator [╳]
我现在已经更加仔细地研究了该标准,并且没有地方说恒定的条件表达式与只有"returned" 表达式具有相同含义被写.
I have now gone through the standard more carefully and nowhere does it say that a constant conditional-expression is the same as if only the "returned" expression would have been written.
true ? <expr1> : <expr2>; // this is not the same as just writing <expr1>;
关于 return *&result; [╳]
在C99中明确指出,*&result
等同于完全,它等同于编写了result
,而在C ++规范中则不是这种情况.
Regarding return *&result; [╳]
In C99 it is explicitly stated that *&result
is the exact equivalent of having written result
instead, this is not the case in the C++ specification.
尽管我们都可以同意,使用*&result
确实会产生与result
相同的 lvalue ,但是根据标准*&result
(当然),表达式不是表达式是非易失性自动对象的名称" .
Though we can all agree on that using *&result
will indeed yield the same lvalue as result
, but according to the standard *&result
(of course) isn't an expression where "the expression is the name of a non-volatile automatic object".
当然,表达式包含一个适当的名称,但不仅如此.
Sure, the expression contains an appropriate name, but it's not just only that.
return result; // #1, OK
return (result); // as described earlier, OK
return true ? result : result; // as described earlier, ill-formed
return rand () ? result : result; // as described earlier, ill-formed
return *&result; // as described earlier, ill-formed
这篇关于隐式将返回的左值视为右值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!