这个报错的中文意思是:非常量引用的初始值必须为左值
最常见的原因有两种:

声明了一个针对常量的引用,例如

#include <iostream>
using namespace std;

int main()
{
    int& i = 10;//这种通常在vs里报错为:非常量引用的初始值必须为左值
    /*在Linux便是invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’*/
    return 0;
}

解决办法

#include <iostream>
using namespace std;

int main()
{
    int x = 10;
    int& i = x;

    return 0;
}

在参数为非常量引用类型的函数中传入常量类型,例如

#include <iostream>
using namespace std;

void fun(int& i)
{
    cout << i;
}

int main()
{
    fun(1);//这种通常在vs里报错为:非常量引用的初始值必须为左值
    /*在Linux便是invalid initialization of non-const reference of type ‘int&’ from an rvalue of type ‘int’*/
    return 0;
}

又如

#include <iostream>
#include <string>
using namespace std;

void fun(string& i)
{
    cout << i;
}

int main()
{
    fun("str");//这种通常在vs里报错为:非常量引用的初始值必须为左值
    /*在Linux便是invalid initialization of non-const reference of type ‘string&’ from an rvalue of type ‘string’*/
    return 0;
}

解决办法均为在参数前面加个const关键字

#include <iostream>
#include <string>
using namespace std;

void fun(const int& i)
{
    cout << i;
}

int main()
{
    fun(1);

    return 0;
}

#include <iostream>
#include <string>
using namespace std;

void fun(const string& i)
{
    cout << i;
}

int main()
{
    fun("str");

    return 0;
}

在编译器中,当我们把引用绑定到一个变量上时,它会创建一个临时变量,在将引用绑定到这个临时变量当中,而我们知道,将引用绑定到一份数据后,就可以通过引用对这份数据进行操作了,包括读取和写入(修改);尤其是写入操作,会改变数据的值。而临时数据往往无法寻址,是不能写入的,即使为临时数据创建了一个临时变量,那么修改的也仅仅是临时变量里面的数据,不会影响原来的数据,这样就使得引用所绑定到的数据和原来的数据不能同步更新,最终产生了两份不同的数据,失去了引用的意义,这是编译器的一个安全机制。

而为这个引用赋予const常量属性后,这个临时变量里的数据就不能修改,所以当然就可以编译通过了。

所以,让函数接收引用参数养成随手加const是个好习惯,扼杀bug于编译的摇篮中。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐