未执行左值到右值转换 [英] Lvalue to rvalue conversion not performed

查看:90
本文介绍了未执行左值到右值转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下函数返回右值

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

Clang的 AST也显示了转化

`-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'






以下代码也执行从左值到右值的转换,这一次是将参数放入函数中。


The following also performs an lvalue to rvalue conversion, this time for the parameter going into the function.

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

AST包含转换

`-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'






据我了解,以同样的方式,以下内容也应要求将左值转换为右值。


As I understand it, in the same way, the following should also require an lvalue to rvalue conversion.

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

但是从不显示在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?

推荐答案


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

Why? Is the conversion optional sometimes?

不需要并且禁止转换。

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

For the class type A, f(a); causes the copy constructor of A to be invoked. The implicitly defined copy constructor takes an lvalue reference (i.e. const A&), and lvalue-to-rvalue conversion is suppressed when binding lvalue-reference.

[dcl.init.ref] /5.1


(5.1)如果引用是左值引用...

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

...

[注:当完成直接与左值的绑定时,不需要通常的左值到右值,数组到指针和函数到指针的标准转换,因此可以抑制这些转换。 。 — end note]

[ 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 ]

这篇关于未执行左值到右值转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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