【问题标题】:References and constants引用和常量
【发布时间】:2016-06-09 06:36:10
【问题描述】:

我们只能将引用绑定到一个对象,而不是一个字面量或一个更通用的表达式的结果。

int i=42;
double d=1.2;
int &r=10;//error:initializer must be an object.
int &r1=d; //error: initializer must be an int object

虽然我们可以将一个常量的引用绑定到一个对象、一个字面量以及一个更通用的表达式的结果,如图所示-

int j=45;
double d=1.2;
const int &r2=j; // works
const int &r2=60; //works
const int &r3=d; //works

Primer中提到的原因是编译器在这里创建了一个'constant int'类型的临时对象。

const int temp=d;
const int &r3=temp;

但如果是这种情况,那么这个逻辑必须适用于上述两种情况,如果引用类型和对象不同,两者都应该起作用。但实际上,如果类型不同,则程序仅在引用类型为“对常量的引用”时才有效,否则会显示错误。为什么?

【问题讨论】:

标签: c++ reference


【解决方案1】:

简单地说:const 引用延长了临时对象的生命周期。这是该语言的一个特性,可以避免可能因临时销毁而产生的悬空引用。

更准确地说,C++ 标准说:

[class.temporary]/p5

在三种上下文中,临时对象在与完整表达式末尾不同的点被销毁 [...] 第三种上下文是引用绑定到临时对象时。

[dcl.init.ref]/p5.2

对“cv1 T1”类型的引用由“cv2 T2”类型的表达式初始化,如下所示:

[..左值和转换案例..]

否则,引用应为对非易失性 const 类型的左值引用(即 cv1 应为 const),或者引用应该是一个右值引用

至于什么是右值/左值,我推荐阅读value categories

如果您正在使用 MSVC,最后给您一点建议:turn your warnings on 针对这个特定问题。

【讨论】:

    猜你喜欢
    • 2011-01-31
    • 2014-05-15
    • 2019-02-05
    • 2011-03-14
    • 2016-08-24
    • 2015-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多