为什么rvalue引用绑定到xvalue在我的代码中不起作用?

Seo*_*ong 14 c++ rvalue lvalue xvalue c++11

我试图理解C++ 11中的左值和右值.所以我写了一个测试代码:

int x = 10;
int foo() { return x; }
int& bar() { return x; }
int&& baz() { return 10; }

int main() {
    int& lr1 = 10;     // error: lvalue references rvalue
    int& lr2 = x;      // ok
    int& lr3 = foo();  // error: lvalue references rvalue
    int& lr4 = bar();  // ok
    int& lr5 = baz();  // error: lvalue references rvalue

    int&& rr1 = 10;    // ok
    int&& rr2 = x;     // error: rvalue references lvalue
    int&& rr3 = foo(); // ok
    int&& rr4 = bar(); // error: rvalue references lvalue
    int&& rr5 = baz(); // ok
}
Run Code Online (Sandbox Code Playgroud)

它工作得很好,所以我插入std :: cout来打印结果.

#include <iostream>

int x= 10;
int foo() { return x; }
int& bar() { return x; }
int&& baz() { return 10; }

int main() {
    int& lr1 = 10;     std::cout << lr1 << std::endl; // error
    int& lr2 = x;      std::cout << lr2 << std::endl; // ok
    int& lr3 = foo();  std::cout << lr3 << std::endl; // error
    int& lr4 = bar();  std::cout << lr4 << std::endl; // ok
    int& lr5 = baz();  std::cout << lr5 << std::endl; // error

    int&& rr1 = 10;    std::cout << rr1 << std::endl; // ok
    int&& rr2 = x;     std::cout << rr2 << std::endl; // error
    int&& rr3 = foo(); std::cout << rr3 << std::endl; // ok
    int&& rr4 = bar(); std::cout << rr4 << std::endl; // error
    int&& rr5 = baz(); std::cout << rr5 << std::endl; // ERROR!?
}
Run Code Online (Sandbox Code Playgroud)

int&& rr5 = baz(); std::cout << rr5; 导致运行时错误,但我不知道它为什么会出错.

我认为返回值baz()将是xvalue,因此它的生命周期会延长.但是当我尝试访问其值时,会发生错误.为什么?

son*_*yao 19

我认为返回值baz()将是xvalue,因此它的生命周期会延长.

起初,什么baz()回报总是悬挂参考.

因为int&& baz() { return 10; },临时寿命没有延长.它是在函数内部构造的,当离开函数时会被销毁,然后baz()总是返回一个悬空引用.

return不扩展语句中函数返回值的临时绑定:它在返回表达式的末尾立即销毁.这样的函数总是返回一个悬空引用.

那么int&& rr5 = baz();,rr5也是一个悬垂的参考; 对它的尊重导致UB,一切皆有可能.

另一方面,如果你改变baz()为按价值返回,一切都会好的; 返回值被复制然后绑定到rr5,然后临时的生命周期延长到生命周期rr5.

生活

  • @CinCout - `rr5`不存储任何东西.它与一个物体绑定在一起.在绑定发生之前,该对象基本上被破坏了. (4认同)
  • @CinCout正如其他人所说,关键是临时是在函数内部构造的,并在函数返回时被销毁,然后被绑定到`rr5`. (3认同)
  • @nm我想这是一个拼写错误(在第二个代码片段中修复). (2认同)