C++ 假设我们有一个右值引用,右值是持久的吗?

C++ 假设我们有一个右值引用,右值是持久的吗?,c++,C++,下面是一个使用boost::typeindex::type_id_和_cvr推断变量类型的示例 包括 包括 包括 包括 define PRINT_TYPEx std::coutw指反汇编的前两行中的临时堆栈对象。临时语句的生命在语句末尾结束。这使得w成为一个悬而未决的引用。这个相同的内存地址稍后会被重用,请参见反汇编中标记为1de4的行,它覆盖了存储在那里的1。另一个现象是,当我们使用自动类型推断时,会忽略所有引用,实际上会发生值复制 #include <memory> #inclu

下面是一个使用boost::typeindex::type_id_和_cvr推断变量类型的示例

包括 包括 包括 包括
define PRINT_TYPEx std::coutw指反汇编的前两行中的临时堆栈对象。临时语句的生命在语句末尾结束。这使得w成为一个悬而未决的引用。这个相同的内存地址稍后会被重用,请参见反汇编中标记为1de4的行,它覆盖了存储在那里的1。

另一个现象是,当我们使用自动类型推断时,会忽略所有引用,实际上会发生值复制

#include <memory>
#include <iostream>
#include <boost/type_index.hpp>
#include <cstdio>


#define PRINT_TYPE(x) std::cout << "type of " #x " is "  << \
    boost::typeindex::type_id_with_cvr<decltype(x)>().pretty_name() << std::endl


int main(){
    int x = 1;
    int *y = &x;

    auto w = std::move(1);
    printf("w=%x\n",w);

    PRINT_TYPE(x);
    printf("w=%x\n",w);

    return 0;
}
int&&w=1;将延长临时文件的使用寿命

move返回一个右值引用,因此,不会对

int&&w=std::move1

w在语句末尾悬空。所以访问它是UB

 int&& w = std::move(1);
    1d99:       c7 45 b0 01 00 00 00    movl   $0x1,-0x50(%rbp)       # <- **-0x50(%rbp) is the address of rvalue 1**
    1da0:       48 8d 45 b0             lea    -0x50(%rbp),%rax
    1da4:       48 89 c7                mov    %rax,%rdi
    1da7:       e8 34 06 00 00          callq  23e0 <_ZSt4moveIiEONSt16remove_referenceIT_E4typeEOS1_>
    1dac:       48 89 45 b8             mov    %rax,-0x48(%rbp)

...

    PRINT_TYPE(x);
    1dc9:   48 8d 35 64 12 00 00    lea    0x1264(%rip),%rsi        # 3034 <_ZStL6ignore+0x23>
    1dd0:   48 8d 3d 49 32 20 00    lea    0x203249(%rip),%rdi        # 205020 <_ZSt4cout@@GLIBCXX_3.4>
    1dd7:   e8 24 fd ff ff          callq  1b00 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>
    1ddc:   48 89 c3                mov    %rax,%rbx
    1ddf:   e8 5e 09 00 00          callq  2742 <_ZN5boost9typeindex16type_id_with_cvrIiEENS0_14stl_type_indexEv>
    1de4:   48 89 45 b0             mov    %rax,-0x50(%rbp)           # <- **-0x50(%rbp) is modified**
    1de8:   48 8d 45 c0             lea    -0x40(%rbp),%rax
    1dec:   48 8d 55 b0             lea    -0x50(%rbp),%rdx
    1df0:   48 89 d6                mov    %rdx,%rsi
    1df3:   48 89 c7                mov    %rax,%rdi
    1df6:   e8 13 04 00 00          callq  220e <_ZNK5boost9typeindex14stl_type_index11pretty_nameB5cxx11Ev>
    1dfb:   48 8d 45 c0             lea    -0x40(%rbp),%rax
    1dff:   48 89 c6                mov    %rax,%rsi
    1e02:   48 89 df                mov    %rbx,%rdi
    1e05:   e8 e6 fc ff ff          callq  1af0 <_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKNSt7__cxx1112basic_stringIS4_S5_T1_EE@plt>
    1e0a:   48 89 c2                mov    %rax,%rdx
    1e0d:   48 8b 05 bc 31 20 00    mov    0x2031bc(%rip),%rax        # 204fd0 <_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GLIBCXX_3.4>
    1e14:   48 89 c6                mov    %rax,%rsi
    1e17:   48 89 d7                mov    %rdx,%rdi
    1e1a:   e8 21 fd ff ff          callq  1b40 <_ZNSolsEPFRSoS_E@plt>
    1e1f:   48 8d 45 c0             lea    -0x40(%rbp),%rax
    1e23:   48 89 c7                mov    %rax,%rdi
    1e26:   e8 45 fc ff ff          callq  1a70 <_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEED1Ev@plt>

#include <memory>
#include <iostream>
#include <boost/type_index.hpp>
#include <cstdio>


#define PRINT_TYPE(x) std::cout << "type of " #x " is "  << \
    boost::typeindex::type_id_with_cvr<decltype(x)>().pretty_name() << std::endl


int main(){
    int x = 1;
    int *y = &x;

    auto w = std::move(1);
    printf("w=%x\n",w);

    PRINT_TYPE(x);
    printf("w=%x\n",w);

    return 0;
}
w=1
type of x is int
w=1