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. 解决方案

  1. 将普通引用改为常量引用(PS:改为常量引用后不能修改绑定的对象,只能读不能写)
bool find_int(const std::vector<int>::iterator &begin, const std::vector<int>::iterator &end, int v)
  1. 修改函数的形参声明,将引用改成普通变量
bool find_int(std::vector<int>::iterator begin, std::vector<int>::iterator end, int v)
  1. 用变量存储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

  1. 为什么方案一可行呢?通过常量引用绑定临时量,临时量就不会销毁了吗?

    1. C++标准:assigning a temporary object to the const reference extends the lifetime of this object to the lifetime of the const reference.
    2. 常量引用会延长临时量的生命周期
  2. 普通引用只能绑定和引用类型相同的左值(PS:函数的返回值不是左值,因为无法对其进行赋值)
  3. 常量引用可以绑定临时量、常量或者可转换为引用类型的变量

6. 参考资料

  1. 常量引用绑定临时量
  2. C++ primer 第五版-P55、P201

C++ non-const lvalue reference cannot bind to a temporary的更多相关文章

  1. error: cannot bind non-const lvalue reference of type

    这种问题一般是因为引用了匿名变量.涉及左值和右值的区别.一般函数的参数如果是一个表达式,那将会产生一个第3方的匿名变量传入这个函数中,此时如果引用,没用什么实际意义. c++中临时变量不能作为非con ...

  2. 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 ...

  3. C++ const用法,看这一篇就够了!

    本文主要介绍const修饰符在C++中的主要用法,下面会从两个方面进行介绍:类定义中使用const.非类定义中使用const 1. 非类定义中使用const 非类定义中使用const是指:在除了类定义 ...

  4. C++ lvalue,prvalue,xvalue,glvalue和rvalue详解(from cppreference)

    General 每一个C++表达式(一个操作符和它的操作数,一个字面值,一个变量名等等)都代表着两个独立属性:类型+属性分类.在现代C++中 glvalue(泛左值) = lvalue (传统意义上的 ...

  5. Value Categories

    Value categories Three primary categories primary categories mixed special Each C++ expression (an o ...

  6. C++11中rvalue references的使用

    Rvalue references are a feature of C++ that was added with the C++11 standard. The syntax of an rval ...

  7. 彻底理解c++的隐式类型转换

    隐式类型转换可以说是我们的老朋友了,在代码里我们或多或少都会依赖c++的隐式类型转换. 然而不幸的是隐式类型转换也是c++的一大坑点,稍不注意很容易写出各种奇妙的bug. 因此我想借着本文来梳理一遍c ...

  8. C++11引用临时变量的终极解析

    工作中遇到一个引用临时变量的问题,经过两天的学习,私以为:不仅弄明白了这个问题,还有些自己的独到见解. 这里使用一个简单的例子来把自己的学习过程和理解献给大家,如果有什么问题请不吝指正.   **** ...

  9. Object lifetime

    Object lifetime Temporary object lifetime Storage reuse Access outside of lifetime Every object has ...

随机推荐

  1. 奇点云 x 阿里云 | 联合发布综合体数字化转型与数据创新解决方案

    2019年7月25日下午,在阿里云峰会上海站,奇点云入选阿里云首批联合解决方案合作伙伴,并联合发布了“综合体数字化转型与数据创新解决方案”,共同探索综合体的智能服务. 关于综合体的数字化转型,奇点云联 ...

  2. JavaEE基础:过滤器、监听器、拦截器,应用...

    写在前面说起Java和C++,很容易想到让人疯狂的指针,Java使用了内存动态分配和垃圾回收技术,让我们从C++的各种指针问题中摆脱出来,更加专心于业务逻辑,不过如果我们需要深入了解java的JVM相 ...

  3. python3多线程应用详解(第三卷:图解多线程中join,守护线程应用)

  4. leaflet本地加载arcgis切片

    var origin = [-20037700, 33711400];//图层起点坐标 var resolutions = [ 8466.6836000338681, // Level 0 4233. ...

  5. 使用mybatis的动态sql解析能力生成sql

    需求: 计算平台,有很多表,打算提供一个基于sql的服务接口, sql不能完全在配置页面写死, 要能根据参数不同执行不同的语义,防止sql个数爆炸 把mybatis原码down下来, 改造一下测试用例 ...

  6. Serializable 接口(序列化)

    目录 Serializable 接口(序列化) 前言 用途 如何实现 异常 serialVersionUID transient关键字 Serializable 接口(序列化) 前言 查看API文档时 ...

  7. 安装centos7后不能联网

    我们在安装centos的minimal版本后,在使用yum安装工具时会提示:cannot find a valid baseurl or repo:base/7/x86_64 这是因为不能联网导致的, ...

  8. firefox上网慢

    由于Chromium浏览器,打字的时候经常会跳字母,所以就换了firefox浏览器,但是FF上网的时候特别慢,而且大部分时间是花费在解析域名上.因此到网上找了许多资料,最终解决方法如下. 1.安装dn ...

  9. python使用pip安装第三方库(工具包)速度慢、超时、失败的解决方案

    人生苦短,我用python!为什么很多人喜欢用python,因为包多呀,各种调包.但是调包有的时候也调的闹心,因为安装包不是失败就是很慢,很影响自己的工作进度,这里给出一个pip快速安装工具包的办法, ...

  10. 用css3实现图片的放大缩小

    记录一个公用的css实现图片的放大缩小 @keyframes scaleDraw { /*定义关键帧.scaleDrew是需要绑定到选择器的关键帧名称*/ 0%{ transform: scale(1 ...