c++ - 未执行左值到右值的转换

标签 c++ clang lvalue-to-rvalue

以下函数returns an rvalue :

int foo()
{
    int x = 42;
    return x;    // x is converted to prvalue
}

Clang 的 AST also shows the conversion :

`-FunctionDecl <line:1:1, line:5:1> line:1:5 foo 'int ()'
  `-CompoundStmt <line:2:1, line:5:1>
    |-DeclStmt <line:3:5, col:15>
    | `-VarDecl <col:5, col:13> col:9 used x 'int' cinit
    |   `-IntegerLiteral <col:13> 'int' 42
    `-ReturnStmt <line:4:5, col:12>
      `-ImplicitCastExpr <col:12> 'int' <LValueToRValue>
                                         ^^^^^^^^^^^^^^
        `-DeclRefExpr <col:12> 'int' lvalue Var 0x627a6e0 'x' 'int'

下面还执行左值到右值的转换,这次是针对进入函数的参数。

void f(int i) {}
int main()
{
    int x{3};
    f(x);
}

AST includes the conversion :

`-FunctionDecl <line:2:1, line:6:1> line:2:5 main 'int ()'
  `-CompoundStmt <line:3:1, line:6:1>
    |-DeclStmt <line:4:5, col:13>
    | `-VarDecl <col:5, col:12> col:9 used x 'int' listinit
    |   `-InitListExpr <col:10, col:12> 'int'
    |     `-IntegerLiteral <col:11> 'int' 3
    `-CallExpr <line:5:5, col:8> 'void'
      |-ImplicitCastExpr <col:5> 'void (*)(int)' <FunctionToPointerDecay>
      | `-DeclRefExpr <col:5> 'void (int)' lvalue Function 0x6013660 'f' 'void (int)'
      `-ImplicitCastExpr <col:7> 'int' <LValueToRValue>
                                        ^^^^^^^^^^^^^^
        `-DeclRefExpr <col:7> 'int' lvalue Var 0x60138a0 'x' 'int'

据我了解,同样,下面也应该需要左值到右值的转换。

struct A{};
void f(A a) {}
int main()
{
    A a;
    f(a);
}

但是它never shows up in the AST :

`-CallExpr <line:6:5, col:8> 'void'
  |-ImplicitCastExpr <col:5> 'void (*)(A)' <FunctionToPointerDecay>
  | `-DeclRefExpr <col:5> 'void (A)' lvalue Function 0x615e830 'f' 'void (A)'
  `-CXXConstructExpr <col:7> 'A' 'void (const A &) noexcept'
    `-ImplicitCastExpr <col:7> 'const A' lvalue <NoOp>
      `-DeclRefExpr <col:7> 'A' lvalue Var 0x615ea68 'a' 'A'

为什么?有时转换是可选的吗?

最佳答案

Why? Is the conversion optional sometimes?

它是不需要的,并且被抑制。

对于类类型 Af(a); 会导致调用 A 的复制构造函数。隐式定义的复制构造函数采用左值引用(即 const A&),并且在绑定(bind)左值引用时会抑制左值到右值的转换。

[dcl.init.ref]/5.1 :

(5.1) If the reference is an lvalue reference ...

...

[ Note: The usual lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard conversions are not needed, and therefore are suppressed, when such direct bindings to lvalues are done. — end note ]

关于c++ - 未执行左值到右值的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50024666/

相关文章:

c - 如何从 Clang 中的 Expr 对象获取 Stmt 类对象

c++ - 类型的非常量引用的无效初始化

java - 将按位运算 (i & 1) 从 C++ 转换为 Java

c++ - cpp中的assert.h有什么用?

c++ - 通过引用传递参数时模板的显式实例化

gcc - gcc和clang在编译时给我一个错误

c++ - 左边的右值

c++ - 类类型的左值到右值转换 : is there copying involved?

c++ - 在 C++ 中搜索文件夹

c++ - 调用了错误的构造函数