2010-01-18 71 views
10

以下代码如何在C++中工作?它合乎逻辑吗?常量引用的文字初始化

const int &ref = 9; 
const int &another_ref = ref + 6; 

为什么C++允许const引用的文字初始化,当非const引用不允许时呢?例如为:

const int days_of_week = 7; 
int &dof = days_of_week; //error: non const reference to a const object 

这可以通过,一个非const引用可被用来改变它指的是变量的值的事实来解释。因此,C++不允许对const变量进行非const引用。

这可能是一个可能的解释? C++不允许:

int &ref = 7; 

因为那是不符合逻辑,但:

const int &ref = 7; 

几乎等同于:

const int val = 7; 

所以文字初始化允许const的变量。

P.S .:我目前正在学习Lippman的C++入门书。

回答

7

所以你可以这样写代码:

void f(const string & s) { 
} 

f("foobar"); 

虽然严格来说什么是真正发生的事情在这里并不被绑定到一个常量引用文字 - 而不是temprary字符串对象被创建:

string("foobar"); 

和这个无名字符串绑定到引用。

请注意,创建非参数引用变量实际上非常不寻常 - 引用的主要目的是作为函数参数和返回值。

6

经常提到可以用文字和临时被初始化,因为你可以平凡它们转化为明确的变量:

int const& ans = 42; 
// tranformed: 
int __internal_unique_name = 42; 
int const& ans = __internal_unique_name; 

或者当寿命不延长,如函数参数:

f("foobar"); 
// transformed: 
{ 
    string __internal_unique_name = "foobar"; 
    f(__internal_unique_name); 
} 

(注意在这种情况下的显式块)

尽管在非常量情况下可能做类似的事情,但这只是不允许使用C++。但是,C++ 0x(下一个标准)将具有r值引用。


如果它是不明确的,ref + 6从您的代码创建一个临时对象,你可以想像为:

int const& ref = int(9); 
int const& another_ref = int(ref + 6); 

// transformed: 
int __A = 9; 
int const& ref = __A; 
int __B = ref + 6; 
int const& another_ref = __B; 

这可能会帮助你理解/可视化所发生的事情,但你应该不要写这样的真实代码。此外,我使用双下划线名称来说明这些名称是实现细节(由编译器使用),不应该由您使用。任何包含相邻下划线的名字都保留给C++实现。

+0

+1。但我认为你的第二个例子将被转换为{__internal_unique_name(“foobar”); f(__ internal_unique_name); } – mmmmmmmm 2010-01-18 18:48:55

+0

@rstevens:无关紧要:转换不能是明确的,在这种情况下它们是相同的。 – 2010-01-18 19:00:33