error:非常量引用只能绑定到左值

今天遇到一个关于C++引用的错误,说实话以前确实一直没注意到过引用还有这个规则

1>------ 已启动生成: 项目: OpenGL, 配置: Debug Win32 ------
1>Game.cpp
1>d:\18482\visual studio\source\repos\opengl\opengl\game.cpp(55): error C2664: “void SpriteRenderer::DrawSprite(Texture2D &,glm::vec2,glm::vec2,GLfloat,glm::vec3)”: 无法将参数 1 从“Texture2D”转换为“Texture2D &1>d:\18482\visual studio\source\repos\opengl\opengl\game.cpp(55): note: 非常量引用只能绑定到左值
1>已完成生成项目“OpenGL.vcxproj”的操作 - 失败。
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========

先解释左值和右值的区别:

  • 从字面意思看,左右值就是在“=”两端的变量或表达式(以前我一直是这样理解的/手动狗头),但其实不是这样的。
  • 左值(Location Value):并不是left_value,指的是可以寻址。指的是如果一个表达式可以引用到某一个对象,并且这个对象是一块内存空间且可以被检查和存储,那么这个表达式就可以作为一个左值。
  • 右值(Read Value):也就是可读。指的是引用了一个存储在某个内存地址里的“数据”

例子:

void func(int &a)
{
    cout << a;
}
void main()
{
    double i = 4;
    func(i);//这里进行了强制类型转换,会产生一个临时变量
}
  • 上面的写法是不合法的,会报错“非常量的引用只能绑定到左值”,按照正常理解 i 其实是一个左值,但是由于定义的 i 和func函数需要的参数并不是相同类型,这里实际上经过了一次强制类型转换,并且生成了一个临时变量(而临时变量都是常量,不能作为左值,只能由const引用,不能改变值),所以这里非const的引用会报错
  • 这里解决方式有两种
    • 让实参和形参类型相同,不必进行强制类型转换
void func(int &a)
{
 cout << a;
}
void main()
{
  int i = 4; //修改i的类型
  func(i);
}
    • 使用右值引用
void func(const int &a)//右值引用
{
  cout << a; 
} 
void main() 
{ 
  double i = 4; 
  func(i);
}

另外,右值引用可以延长临时变量的生命周期,比如这个例子:

int func(int a)
{
return a += 10;      //函数返回值也是一个临时变量 } void main()
{
  int i = 10;   const int &b = func(i);  //变量a是对函数返回值(临时变量)的引用,因此函数返回值不会在此时立即销毁,而是一直延续到整个程序结束   cout<<b; }

 

posted @ 2020-03-10 17:12  无发可理的理发师  阅读(2399)  评论(0编辑  收藏  举报