ISO C ++ 2003标准中不允许引用参考,但为什么编译器允许它?

时间:2014-07-27 07:24:38

标签: c++ visual-c++ gcc reference

根据ISO C ++ 2003标准第8.3.2节

  

“不允许引用引用”

但我尝试在Visual C ++和Ideone中使用以下代码,两个编译器都成功运行此代码。

Ideone GCC C++4.3.2

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;
}

在查看编译器的这种行为后我真的很困惑;有人可以解释一下吗?

4 个答案:

答案 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;

然后iref_i是同一变量的替代名称。说其中一个是参考并且其中一个不是参考没有用,因为没有可能的程序可以区分&#34;哪个是&#34;。

该代码与以下内容完全相同:

int ref_i = 2;
int &i = ref_i;