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

    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
  • 相关阅读:
    wiki iso88591字符表的解释
    [c]字符1一维数组求长度
    vim 用户配置
    PHP中向浏览器输出图片
    如何及时取消 BackgroundWorker 组件的后台工作
    python basic
    php5.1中的时区设置。
    MyBatis的深入原理分析之1架构设计以及实例分析
    hibernate缓存:一级缓存和二级缓存
    Spring 注解(Annotation)代替XML实现零配置
  • 原文地址:https://www.cnblogs.com/wengle520/p/12449931.html
Copyright © 2020-2023  润新知