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

时间:2014-07-12 09:47:01

标签: c++ reference rvalue-reference rvalue

这是一个简单的函数,它将两个整数相加。现在这里的参数是整数引用。

#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),因为rvalues(此处为2和5)与函数&#39; sum&#39;中的参考变量之间不能存在绑定。但是如果将函数定义修改为

,它就可以工作
int sum (const int& a, const int& b)
{
    return (a + b);
}

那么const限定符会发生什么变化,现在甚至引用变量都可以绑定到rvalues?

4 个答案:

答案 0 :(得分:4)

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

但是,rvalue表达式背后经常有对象,修改这些对象(例如窃取其资源)会很有用。这正是引入右值参考的原因。

答案 1 :(得分:1)

Rvalues和temporaries的行为类似于只读引用。因此将它们绑定到非const引用会违反这种性质。将引用声明为const,即表示您正在填写只读合同。

在您的特定情况下,整数23等被称为数字,并且本质上是常量(具有固定值)。在C ++中,修改常量是未定义的行为,因此您的数字仅绑定到const引用。

答案 2 :(得分:0)

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

rvalue无法绑定到第一个sum int&中的非常量左值引用,您需要const T&,因此稍后函数适用于这两个。

答案 3 :(得分:-1)

在C ++ 11中,您可以将其更改为以下内容,使其始终有效,无论您传递的是什么:

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

它会为您提供25的非const引用(即您可以通过sum(2, 5)和{{1}修改a来电中的值})。这是安全的,并且不会产生任何奇怪的副作用,即使它是临时对象而不是基元(如b),因为string("foo")的参数没有名称。他们没有名字会让你无法以任何方式观察修改。