c++ - 引用的类型转换

标签 c++ reference type-conversion

我发现 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)到引用时临时的生命周期延长。

  • doubleint 的隐式转换。

当我向 Bjarne 询问生命周期延长的理由时,在过去,当每个人(包括 Bjarne)都使用 comp.lang.c++ Usenet 组时,他回答说这主要是为了规则的一致性。

doubleint 的潜在且通常会破坏信息的隐式转换,以及通常从任何内置数字类型到另一个数字类型的隐式转换,是来自旧的 C天。在 C++11 及更高版本中,您可以使用花括号初始化器来限制允许的转换。因此,如果你写

const int &i = {b};

...那么对于 b 类型为 double 的情况,代码将无法编译,因为这将是一个缩小转换 .

当然,这对于例如输入 short(不再是缩小转换)没有帮助,但它有一点帮助。

关于c++ - 引用的类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34178350/

相关文章:

c++ - 限制 CPU 速度以进行分析

c++ - 包含对其他对象的引用的对象的深层拷贝

JavaScript 类型强制首选项

c++ - 从类到 double 的隐式转换

c# - Azure 发布会错过引用项目引用的程序集

Java <-> Scala 转换 - "value is not a member of"

c++ - Pointer-to- "inner struct"成员是否被禁止?

c++ - 无法打开使用 ofstream 创建的文件

c++ - 我一直收到此调试断言失败?表达式 : list iterator not dereferenceable

java - 如何创建一个不引用另一个的 Arraylist?