C++ non-const lvalue reference cannot bind to a temporary
1. 问题代码
#include <iostream>
#include <vector>
//注意begin和end形参都声明为引用
bool find_int(std::vector<int>::iterator &begin, std::vector<int>::iterator &end, int v){
while(begin != end){
if(*begin == v)
return true;
begin++;
}
return false;
}
int main(){
std::vector<int> a(3, 100);
//a.begin()和a.end()的返回值作为实参传入find_int中
std::cout << find_int(a.begin(), a.end(), 100) << std::endl;
}
2. 编译错误
g++ -Wall -std=c++11 -o hello hello.cpp

3. 原因分析
non-const lvalue reference cannot bind to a temporary
根据编译错误提示可以知道,不能将形参begin、end绑定到a.begin()和a.end()的返回值,因为该返回值是一个临时量,临时量的生命周期可能在a.begin()和a.end()执行完后就结束了。因此编译器认为普通引用绑定一个临时量,在find_int函数中可能会修改这个临时量,然而此时临时量可能已经被销毁,从而导致一些未定义的行为,因此编译器不允许将普通引用绑定到一个临时量上。
4. 解决方案
- 将普通引用改为常量引用(PS:改为常量引用后不能修改绑定的对象,只能读不能写)
bool find_int(const std::vector<int>::iterator &begin, const std::vector<int>::iterator &end, int v)
- 修改函数的形参声明,将引用改成普通变量
bool find_int(std::vector<int>::iterator begin, std::vector<int>::iterator end, int v)
- 用变量存储a.begin()和a.end()的返回值
std::vector<int>::iterator begin = a.begin();
std::vector<int>::iterator end = a.end();
std::cout << find_int(begin, end, 100) << std::endl;
5. Tips
- 为什么方案一可行呢?通过常量引用绑定临时量,临时量就不会销毁了吗?
- C++标准:assigning a temporary object to the const reference extends the lifetime of this object to the lifetime of the const reference.
- 常量引用会延长临时量的生命周期
- 普通引用只能绑定和引用类型相同的左值(PS:函数的返回值不是左值,因为无法对其进行赋值)
- 常量引用可以绑定临时量、常量或者可转换为引用类型的变量
6. 参考资料
- 常量引用绑定临时量
- C++ primer 第五版-P55、P201
C++ non-const lvalue reference cannot bind to a temporary的更多相关文章
- error: cannot bind non-const lvalue reference of type
这种问题一般是因为引用了匿名变量.涉及左值和右值的区别.一般函数的参数如果是一个表达式,那将会产生一个第3方的匿名变量传入这个函数中,此时如果引用,没用什么实际意义. c++中临时变量不能作为非con ...
- C++之error: cannot bind non-const lvalue reference of type ‘myString&’ to an rvalue of type ‘myString’
先看代码(不想看代码可以直接看代码后的问题描述) //header.h #ifndef _HEADER_H #define _HEADER_H #define defaultSize 128 #inc ...
- C++ const用法,看这一篇就够了!
本文主要介绍const修饰符在C++中的主要用法,下面会从两个方面进行介绍:类定义中使用const.非类定义中使用const 1. 非类定义中使用const 非类定义中使用const是指:在除了类定义 ...
- C++ lvalue,prvalue,xvalue,glvalue和rvalue详解(from cppreference)
General 每一个C++表达式(一个操作符和它的操作数,一个字面值,一个变量名等等)都代表着两个独立属性:类型+属性分类.在现代C++中 glvalue(泛左值) = lvalue (传统意义上的 ...
- Value Categories
Value categories Three primary categories primary categories mixed special Each C++ expression (an o ...
- C++11中rvalue references的使用
Rvalue references are a feature of C++ that was added with the C++11 standard. The syntax of an rval ...
- 彻底理解c++的隐式类型转换
隐式类型转换可以说是我们的老朋友了,在代码里我们或多或少都会依赖c++的隐式类型转换. 然而不幸的是隐式类型转换也是c++的一大坑点,稍不注意很容易写出各种奇妙的bug. 因此我想借着本文来梳理一遍c ...
- C++11引用临时变量的终极解析
工作中遇到一个引用临时变量的问题,经过两天的学习,私以为:不仅弄明白了这个问题,还有些自己的独到见解. 这里使用一个简单的例子来把自己的学习过程和理解献给大家,如果有什么问题请不吝指正. **** ...
- Object lifetime
Object lifetime Temporary object lifetime Storage reuse Access outside of lifetime Every object has ...
随机推荐
- EF 执行存储过程
- LGOJ3804 【模板】后缀自动机
题目链接: link 题目大意 给定一个只包含小写字母的字符串\(S\), 请你求出 \(S\) 的所有出现次数不为 \(1\) 的子串的出现次数乘上该子串长度的最大值. Solution 预处理出每 ...
- VirtualBox虚拟机Ubuntu设置共享文件夹,并自动挂载
一.环境 Win10系统,VirtualBox-5.1.22-115126+Ubuntu16.04(64位)虚拟机 二.目的 在Ubuntu中能够共享Win10中的某个文件夹,而且能够自动挂载 ...
- 利用离散 Fourier 变换解一元二次方程
设二次方程$$x^2+bx+c=0$$的两个根分别为 $x_1,x_2$.则$$(x-x_1)(x-x_2)=x^2+bx+c.$$因此$$\begin{cases} x_1+x_2=-b\\x_1 ...
- python与模块的导入方式
今日所得 模块 import from...import... 循环导入 相对导入 绝对导入 软件开发目录规范 模块 模块:是一系列功能的集合体 模块的三种来源:1.内置模块(Python解释器自带的 ...
- FPGA浮点数定点数的处理
http://blog.chinaaet.com/justlxy/p/5100053166大佬博客,讲的非常有条理的 1,基础知识 (1)定点数的基础认知: 首先例如一个16位的数表示的定点数的范围是 ...
- CAD安装未完成,某些产品无法安装的解决方法
CAD提示安装未完成,某些产品无法安装该怎样解决呢?,一些朋友在win7或者win10系统下安装CAD失败提示CAD安装未完成,某些产品无法安装,也有时候想重新安装CAD的时候会出现本电脑window ...
- pycharm全局搜索快捷键无反应
原因:和搜狗输入法的快捷键冲突
- Handler机制中的消息队列
--> 学习自蘑菇街大佬 Handler机制可以看成是一个消息阻塞队列,当有消息时立即处理消息,没有消息时则阻塞.在Android系统中APP启动后很快进入死循环,不断读取MessageQueu ...
- nginx 代理第三方邮件站点
需求:公司业务服务器使用的是阿里云,要求内网(仅有内网IP)所有流量走网关服务器(有外网IP及内网IP),内网服务器需要调用一个公网上的第三方邮件站点.在参考了https://www.linuxba. ...