Const和非const引用绑定

时间:2013-06-22 22:41:27

标签: c++ compiler-errors

void swap(int& a, int& b) {}

void copy(int& a, const int& b) {}

int main() {
   int a=1;
   unsigned b=2;

   swap(a, b);
   copy(a, b);
}

C ++语言,g ++编译器。

请告诉我为什么 copy -function调用中没有编译错误,但在 swap -function触发器invalid initialization of reference of type ‘int&’ from expression of type ‘unsigned int’

抱歉我的英语不好。

2 个答案:

答案 0 :(得分:4)

短篇小说

首先 - 将U类型的表达式与资格cv2的参考绑定引用到具有限定条件T的类型cv1的引用的规则L。:< / p>

  

cv1 T的引用可以通过类型cv2 U

的表达式初始化      
      
  • 如果引用是左值引用和初始化表达式

         
        
    • 是左值,cv1 T参考兼容cv2 U
    •   
    • 有一个班级类型[...]。
    •   
  •   
  • 否则,cv1应为const,或者引用应为右值参考。

  •   
     如果cv1 Tcv2 U的类型相同(或{{1}的基数},则

T参考兼容U如果U等于cv1(或更高)。

不幸(或幸运的是!!;))具有非常量左值参考参数的函数不能使用非参考兼容类型的左值调用(或者在没有可靠转换的类类型的情况下调用参考兼容类型的参数。)

详细

让我们考虑一个带整数引用的函数和一个具有常量整数引用参数的函数。

cv2

让我们看看单个有符号值和另一个无符号值:

void doSomething (int & x)
{
  // do some READ & WRITE stuff with x
  x = x+5;
}

int doSomethingElse (int const & x)
{
  // do some READ ONLY stuffwith x
  return 3*x;
}

现在我们将名为 int a = 1; unsigned int b = 2; 的{​​{1}}传递给int

a

这里没有魔法,引用doSomething()绑定到 // works since x of doSomething can bind to a doSomething(a); // let's try to expand/"inline" what is happening { int & x = a; x = 5; } 并设置为5(因此也是a)。细

现在我们尝试将x传递给同一个函数。但是......

a

我们开始遇到问题,并且b调用 // ... it doesn't work/compile since // unsigned int is not reference compatible to int doSomething(b); // compile error here // what's going on here { int & x = b; // unsigned value cannot bind to a non-const lvalue reference! // compile error here x = 5; } 将无法编译。

现在让我们看看const引用函数。通过doSomething显然不会再出现问题。 const int引用绑定到b值。

a

好吧好吧。 int将为int c = doSomethingElse(a); // let's do some naive inlining again int c; { int const & x = a; c = 3*x; }

如果我们将c传递给该函数会发生什么?标准说,在这种情况下,使用复制初始化规则从初始化表达式创建并初始化类型3*a的临时表。

b

答案 1 :(得分:0)

对于交换第二个param想要int&amp;并传递未签名的b。它并不像int&amp;没有任何帮助。

复制需要const int&amp;,允许使用临时的。你传递它unsigned,可以隐式转换为int,并且int临时可以传递给copy。

最大的区别在于第二种情况不会修改第二种情况,因此它可以在引擎盖下更换。如果交换案例允许临时,你将与临时交换,并保持b不变,这几乎不是任何人想要的。