为什么const限定符允许临时对象或右值

Why does the const qualifier allow temporary objects or rvalues?

本文关键字:临时对象 const 为什么      更新时间:2023-10-16

这是一个简单的函数,对两个整数求和。这里的形参是整型引用。

#include <iostream>
#include <cstdlib>
using namespace std;
int sum (int &a, int &b)
{
  return(a + b);
}
int main()
  int a = 23, b = 34;
  cout << sum(a, b) << endl; // this works
  cout<< sum(2, 5) <<endl; // as expected, this does not work; compilation fails
  return(0);
}

所以它不能与sum(2,5)一起工作,这是可以理解的,因为在函数'sum'中右值(这里是2和5)和引用变量之间不能绑定。但是,如果将函数定义修改为

,则可以工作。
int sum (const int& a, const int& b)
{
    return (a + b);
}
那么const限定符做了什么改变,现在甚至连引用变量都可以绑定到右值?

左值表示对象,右值表示值(粗略地说)。将右值绑定到非const左值引用将允许您修改 -这到底是什么意思?如果您在函数中编写了a = 3,那么您将尝试修改值2以使其成为3。这在概念上讲不通。然而,const左值引用不允许修改,只允许你观察一个值,这是有意义的。

然而,右值表达式后面通常有对象,修改这些对象(例如窃取其资源)是有用的。这正是引入右值引用的原因。

右值和临时值的行为类似于只读引用。因此,将它们绑定到非const引用将违反这一性质。声明一个引用为const,你就完成了只读契约。

在您的特殊情况下,整型(23等)被称为数字,并且本质上是常量(具有固定值)。在c++中,修改常量是未定义的行为,所以你的数字只能绑定到const引用。

sum(2, 5)中2和5是右值

右值不能绑定到一个非const左值引用,就像你的第一个sum int&一样,你需要const T&,所以后面的函数都适用

在c++ 11中,您可以将其更改为以下内容以使其始终工作,无论您传递什么:

int sum (int &&a, int &&b)
{
    return(a + b);
}

它会给你一个对25的非const引用(即你可以通过ab修改sum(2, 5)调用中的值)。这是安全的,不会产生任何奇怪的副作用,即使它是临时对象而不是原语(如string("foo")),因为sum()的参数没有名称。由于它们没有名称,因此您无法以任何方式观察修改