隐式将返回的左值视为右值 [英] Implicitly treating returned lvalue as rvalue

查看:140
本文介绍了隐式将返回的左值视为右值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

12.8复制和移动类对象[class.copy]§31和§32说:

12.8 Copying and moving class objects [class.copy] §31 and §32 say:

在具有类返回类型的函数中的return语句中,当表达式是具有相同含义的非易失性自动对象(函数或catch子句参数除外)的名称时cv-unqualified type作为函数返回类型,可以通过将自动对象直接构造为函数的返回值来省略复制/移动操作

in a return statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function or catch-clause parameter) with the same cv-unqualified type as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function’s return value

当满足或将要满足复制操作的省略标准时,除非源对象是函数参数,并且要复制的对象由左值指定,否则重载分辨率以选择用于首先执行复制操作,就好像该对象是由右值指定的.

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.

5.1.1/1   一般    [expr.prim.general]

带括号的表达式是主表达式,其类型和 值与所附表达式相同.这 括号的存在不影响表达式是否为左值.除非另有说明,否则带括号的表达式可以与使用封闭表达式的上下文完全相同,并且具有相同的含义.

5.1.1/1      General      [expr.prim.general]

A parenthesized expression is a primary expression whose type and value are identical to those of the enclosed expression. The presence of parentheses does not affect whether the expression is an lvalue. The parenthesized expression can be used in exactly the same contexts as those where the enclosed expression can be used, and with the same meaning, except as otherwise indicated.


关于constexpr 条件运算符 [╳]

我对常量表达式和他的条件运算符解释标准的方式是,return true ? result : result的用法非常好-由于它是一个常量表达式,因此具有与 return结果相同的结果;


Regarding the constexpr conditional operator [╳]

The way I interpret the standard in regards to constant-expressions and he coditional operator is that the use of return true ? result : result is well-behaved since it is a constant expression and therefore equivalent to return result;

我现在已经更加仔细地研究了该标准,并且没有地方说恒定的条件表达式与只有"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

这篇关于隐式将返回的左值视为右值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆