根据ISO C ++ 2003标准第8.3.2节
“不允许引用引用”
但我尝试在Visual C ++和Ideone中使用以下代码,两个编译器都成功运行此代码。
int main()
{
int i=2;
int &ref_i=i;
int &ref_ref_i=ref_i; // should be an error according to c++ 2003 standard
cout<<i<<endl<<ref_i<<endl<<ref_ref_i;
return 0;
}
在查看编译器的这种行为后我真的很困惑;有人可以解释一下吗?
答案 0 :(得分:14)
您不会在代码中创建引用引用。
这只是另一个int&
,即两者都是对int
(T.C。shows an example非法C ++ 03引用参考文献)
C ++ 11标准部分§8.3.2通过一个例子明确地显示了这一点(当然,不允许引用引用的参考文献在C ++ 03和C ++ 11之间没有变化,但参考折叠在C中是新的++ 11):
如果typedef-name(7.1.3,14.1)或decltype-specifier(7.1.6.2)表示类型TR是对类型T的引用,则尝试创建类型“对cv TR的左值引用” “创建类型”对“T”的左值引用,而尝试创建类型“对cv TR的右值引用”则创建类型TR。
int i;
typedef int& LRI;
typedef int&& RRI;
LRI& r1 = i; // r1 has the type int&
const LRI& r2 = i; // r2 has the type int&
const LRI&& r3 = i; // r3 has the type int&
答案 1 :(得分:2)
对引用的引用在C ++ 03中是非法的,但您没有创建它。
以下代码尝试创建对引用的引用:
int main(){
int c = 0;
typedef int & IREF;
int & c1 = c;
IREF & c2 = c1;
int & & c3 = c1;
}
当g ++处于C ++ 03模式时,...和fails miserably:
> g++-4.9 -std=c++03 -O2 -Wall -pedantic -pthread main.cpp
main.cpp: In function 'int main()':
main.cpp:5:12: error: cannot declare reference to 'IREF {aka int&}'
IREF & c2 = c1;
^
main.cpp:6:13: error: cannot declare reference to 'int&', which is not a typedef or a template type argument
int & & c3 = c1;
^
正如另一个答案中所述,C ++ 11添加了新的参考折叠规则,使IREF & c2 = c1;
格式正确但不int & & c3 = c1;
,int &
既不是 typedef-name 也不是 decltype-specifier 。
答案 2 :(得分:1)
它不是对引用的引用,在引用声明之后,使用表达式中的名称就像使用对象本身的名称一样。
5表达式6.如果表达式最初具有“对T的引用”类型(8.3.2,8.5.3),则在任何类型之前将类型调整为“T” 进一步分析,表达式指定由引用表示的对象或函数,表达式是左值。
所以当你这样做时:
int &ref_ref_i=ref_i;
ref_ref
实际上是对原始变量i
的引用。
如果您尝试做这样的事情:
int i = 6;
int &ri = i;
int &&ri = ri;
你会得到一个编译器错误,就像你写的引用所示。
注意:此答案仅适用于C ++ 2003和先前标准,并未考虑右值引用。
答案 3 :(得分:0)
完成后:
int i=2;
int &ref_i=i;
然后i
和ref_i
是同一变量的替代名称。说其中一个是参考并且其中一个不是参考没有用,因为没有可能的程序可以区分&#34;哪个是&#34;。
该代码与以下内容完全相同:
int ref_i = 2;
int &i = ref_i;