2015-12-30 54 views
2

我是C++新手。我试图学习const的概念。有人能告诉我为什么第一个声明是非法的,而第二个声明是合法的?为什么int&r = 0是非法的,而const int&r = 0是合法的?

int i = -1, &r = 0;   

const int i = -1, &r = 0; 
+3

[可能为[对常量引用的文字初始化]重复(http://stackoverflow.com/questions/) 2088259/literal-initialization-for-const-references) – Zeta

+1

@Zeta:建议dup表示*“C++不允许:'int&ref = 7;'因为这是不合逻辑的,“* - 对于OP来说,这里的问题 - *”为什么第一个非法,而第二个合法“*是显而易见的,另一个问题是关于'const'引用,而不是与非'const'的对比。 –

回答

8

i是一个红色的鲱鱼在这里,问题是int &r = 0;const int &r = 0;

一个非const左值引用必须直接绑定到左值。 0不是左值,所以int &r = 0;失败。

常量左值引用可能会绑定到右值。发生这种情况时,不会直接绑定。相反,创建一个临时(const int这里的类型)并从右值复制初始化。由于这种绑定,临时性的生命期延长了。

所以const int &r = 0;是合法的,有const int __temp = 0; const int &r = __temp;

+4

注意:我使用双下划线来表示这是伪代码 –

4

int i = -1, &r = 0;是一样的:

int i = -1; 
int &r = 0; 

这里的问题是,你可以不写int &r = 0;,因为参考的初始化需要的初始化是一个左值(一个对象,其地址 可以采取),而文字0不是。

但是const引用的初始值不需要是左值,所以const int &r = 0;没问题。

1

int i = -1, &r = 0;类似的效果基本等同于写

int i = -1; 
int &r = 0 

第二条语句试图非const左值绑定到0,这是不是一个完全左值(0不是可以取地址的对象)。然而,它是一个const左值,因为它被绑定(不是直接通过)到右值。

2

i = -1,位创建i变量初始化为-1,反而使得该来后,没有引用任何区别,所以让我们关注:

int &r = 0;  // illegal 
const int &r = 0; 

const int&版本做什么是延长值的生命周期它必然是:换句话说,0值保持在r以上,直到r定义的范围结束。

很容易指出的是,同样的慷慨大方,没有延伸到int&版“因为它不是一个左值”。为什么在C++ FAQ讨论的更有趣的问题:

在C++中,非const引用可以绑定到左值和const引用可以绑定到左值或右值,但可以结合什么到非常量值。这是为了防止人们在使用新价值之前改变临时销售价值。例如:

void incr(int& a) { ++a; } 
int i = 0; 
incr(i); // i becomes 1 
incr(0); // error: 0 is not an lvalue 

如果增量(0)被允许或者一些临时性的,没有人见过将递增或 - 差远了 - 0值将成为1后者听起来很愚蠢,但实际上在早期的Fortran编译器中存在一个像预留内存位置以保持值0那样的错误。

+1

由于C++ 11,我们有'int&&r = 0;'这是合法的,并且因为您提到 –

+1

@ M.M。 “int &&”函数参数的一个主要区别是它们是明确输入的,并且引入了'std :: move',以确保调用代码明确地确认它在哪里可能是令人惊讶和有问题的,而'int&'暗示某种方式的输出和有临时约束的临时性更可能是偶然发生的。 –

相关问题