当前位置: 首页 > news >正文

未加cont修饰的左值引用不能绑定到右值

目录

一、问题背景

二、错误分析

三、警告分析


一、问题背景

在initial value of reference to non-const - C++ Forum看到如下有问题的代码,编译如下代码看看

#include <iostream>
#include <cmath>

int g(double x) { return std::floor(x); }
int&& i(double x) { return g(x); }

void Do_Type_deduction()
{
    auto& li = i(8.8);
}   

int main()
{
    Do_Type_deduction();
    std::cout<<"exit"<<std::endl;
    return 0;
}

g++编译

test.cpp: In function ‘int&& i(double)’:
test.cpp:5:29: warning: returning reference to temporary [-Wreturn-local-addr]
    5 | int&& i(double x) { return g(x); }
      |                            ~^~~
test.cpp: In function ‘void Do_Type_deduction()’:
test.cpp:9:17: error: cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
    9 |     auto& li = i(8.8);
      |                ~^~~~~

cpp.sh中编译

main.cpp:5:28: warning: returning reference to local temporary object [-Wreturn-stack-address]
int&& i(double x) { return g(x); }
                           ^~~~
main.cpp:9:11: error: non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'
    auto& li = i(8.8);
          ^    ~~~~~~
1 warning and 1 error generated.

二、错误分析

error: cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’和error: non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'的含义是一样的。代码第9行中的i(8.8)返回的是int的右值引用。li类型会被推导为int&类型,是一个未加const的左值引用。c++语法规定,未加const的左值引用是不能绑定到右值的,所以第9行报错。这一条规则也是c++类拷贝构造函数和类赋值运算符重载函数的形参要加const修饰的理由,因为从右值对象拷贝构造新对象和从右值对象赋值到目标对象的需求是存在的。

c++类拷贝构造函数和类赋值运算符重载函数的形参为什么要加const?-CSDN博客

所以只需将第9行改成const auto&li = i(8.8);编译报错即可解决。

三、警告分析

再来看代码第5行的警告。

在代码中,函数i被定义为返回一个右值引用int&&。g(x)调用返回的是一个int类型的临时对象(右值)。右值引用通常用于绑定到临时对象,并且允许对这些临时对象进行移动操作。但是不能直接将一个临时对象的右值引用返回,因为当函数返回时,这个临时对象的生命周期就结束了,返回的右值引用将变成一个悬空引用,指向一个已经被销毁的对象,这会导致未定义行为。

在c++中,函数返回右值引用时,通常是为了移动语义,即返回一个对象的所有权,但前提是这个对象的生命周期要能够延长到函数外部。而这里g(x)返回的是一个临时值,它的生命周期在i函数返回时就结束了。

相关文章:

  • Python队列模块全解析:从线程间通信到高效双端队列
  • 萨班斯-奥克斯利法案(Sarbanes-Oxley Act, SOX):公司财务透明度的守护者(中英双语)
  • C/C++ | 每日一练 (2)
  • 机器学习_17 K近邻算法知识点总结
  • 解决 Linux 中搜狗输入法导致系统崩溃的问题【fcitx 】【ibus】
  • C++效率掌握之STL库:vector函数全解
  • 【项目实战】日志管理和异步任务处理系统
  • Golang学习笔记_32——适配器模式
  • QML DropShadow详解及使用方法
  • 跟着 Lua 5.1 官方参考文档学习 Lua (4)
  • 在 Spring 怎么解决循环依赖的问题?
  • 【Pandas】pandas Series idxmax
  • 计算机视觉-OpenCV图像处理
  • 【binlog和redolog有什么区别?】
  • Python数据类革命:用@dataclass解放你的双手
  • VMware安装教程
  • 什么情况下索引会失效
  • go设置镜像代理
  • psacct 简介
  • 5.【线性代数】—— 转置,置换和向量空间
  • wordpress站群seo/郑州网络推广团队
  • 电商网站平台建设资金预算/网站备案查询工信部官网
  • 珠海建设企业网站的公司/网站seo教程
  • 网站做电子公章违法吗/大一网页设计作业成品
  • 上海网站建设电/seo新站如何快速排名
  • 百度做一个网站怎么做呢/app广告推广