我发现 const 引用有一种意想不到的行为:
#include <iostream>
using namespace std;
template <typename T>
void myfunction() {
T b = 30;
const int &i = b;
cout << "Before change: " << i << endl;
b = 33;
cout << "After change: " << i << endl;
}
int main() {
cout << "int" << endl;
myfunction<int>();
cout << endl;
cout << "double" << endl;
myfunction<double>();
}
这给出了以下结果:
int
Before change: 30
After change: 33
double
Before change: 30
After change: 30
据我了解,在第二种情况下,&i 并不引用 b,因为它是 double 型,而是引用了一个临时对象。这也是改变b时i的值没有改变的原因。
但是为什么这种行为会被允许呢?在我看来,这是违反直觉的。仅使用 const int i = b 是否有任何性能优势?
最佳答案
你通常可以想到
const int &i = b;
作为
int const* const p_i = &b;
自动取消引用,例如(但不要太字面意思!)
#define i (*p_i)
第一个 const
表示您无法通过指针/引用更改 b
。但您可以通过其他方式更改它。然后您通过指针/引用看到的内容就会发生变化。
在 b
类型为 double
的情况下,引用不能直接引用它。然后你得到的是一个临时 int
,从double
转换而来,它的生命周期被延长到引用的生命周期(以及指针 View )事情有点崩溃!)。在这种情况下,对原始文件所做的更改不会反射(reflect)在引用引用的临时文件中。
顺便说一句,这种别名(两种或多种方式引用同一事物,具有不同的限制)是通过引用传递 const 的原则上的问题。令人高兴的是,这在实践中并不是什么大问题。事实上,除了创建愚蠢的示例来教授技术可能性之外,我从未遇到过它。
关于
” But why is such a behavior even allowed?
…这询问了两个问题:
绑定(bind)到引用时临时的生命周期延长。
从
double
到int
的隐式转换。
当我向 Bjarne 询问生命周期延长的理由时,在过去,当每个人(包括 Bjarne)都使用 comp.lang.c++ Usenet 组时,他回答说这主要是为了规则的一致性。
从 double
到 int
的潜在且通常会破坏信息的隐式转换,以及通常从任何内置数字类型到另一个数字类型的隐式转换,是来自旧的 C天。在 C++11 及更高版本中,您可以使用花括号初始化器来限制允许的转换。因此,如果你写
const int &i = {b};
...那么对于 b
类型为 double
的情况,代码将无法编译,因为这将是一个缩小转换 .
当然,这对于例如输入 short
(不再是缩小转换)没有帮助,但它有一点帮助。
关于c++ - 引用的类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34178350/