常见推导

  • 1 auto: 产生拷贝,可以修改
  • 2 auto&: 左值引用,接受左值,可以修改
  • 3 const auto&: const引用,可以接受左右值,不可修改
  • 4 auto&&: 万能引用,可以接受左右值,const引用时不能修改
int a = 100;
const int b = 100;
auto a1 = 3; // a1为int
auto a2 = a; // a2为int

auto& a3 = a;// a3为int&,左引用

auto&& a4 = a;// a4为int&,左引用
auto&& a5 = 102;// a5为int&&,右引用
auto&& a6 = b;// a6为const int&,左引用

const auto& a7 = b;// a7为const int&,左引用
const auto&& a8 = 103;// a8为const int&&,右引用

auto* p1 = &a;// p1为int*
const auto* p2 = &a;// p2为const int*
auto p3 = &TestType::v1; // p3为int TestType::*,成员对象指针

auto在一行定义多个变量时,各个变量的推导不能产生二义性,否则编译失败

auto d = 0, f = 1.0; // error,0和1.0类型不同,对于编译器有二义性,没法推导

函数的返回值

//返回R-value
std::string func() {
    return "hello";
}
auto&& ref = func();

右值引用(使用 &&)绑定到右值,但它不会自动进行移动语义。在这种情况下,右值引用 auto&& ref 绑定到了一个临时的 std::string 对象。根据引用折叠规则,当引用绑定到右值时,它会延长临时量(在这种情况下是右值)的生命周期。

为了延长临时量的生命周期,编译器会执行复制构造函数来创建 ref 对象,而不是执行移动构造函数。这是因为一个右值引用绑定到右值,编译器不能假设它是一个独有的资源,因此使用复制而不是移动。

因此,根据示例代码,auto&& ref = func(); 会执行复制构造函数来创建 ref 对象,而不是 移动构造函数 ,产生了一个副本。

如果你想使用移动构造函数来避免复制,你可以将返回值类型声明为右值引用,比如 std::string&& func() { ... }。这样,在 auto&& ref = func(); 的初始化过程中,右值引用 ref 可以绑定到 临时的右值对象 ,并执行移动构造函数来创建 ref,从而避免了复制。
    
    
int func(){ int a=10; return a;}的返回值是左值?还是右值?
posted on 2024-03-15 08:47  Getone超  阅读(15)  评论(0编辑  收藏  举报