c++ - 临时初始化和引用初始化

我正在尝试了解引用初始化的方式。例如,让我们看一个典型的例子。

double val = 4.55;
const int &ref = val;

我可以想到上述代码段中发生的事情的两种可能性。

可能性1

通常的解释如下:

这里是 int 类型的临时值(prvalue)具有值(value) 4创建然后引用 ref绑定(bind)到这个临时的(prvalue)int对象而不是绑定(bind)到变量val直接地。发生这种情况是因为变量的类型 val右边是double而在左侧,我们有一个int的引用强>。但是要将引用绑定(bind)到变量,类型应该匹配。此外,临时纯右值的生命周期得到延长。

可能性2

我认为还有另一种可能发生的情况如下:

这里是 int 类型的临时值(prvalue)具有值(value) 4被 build 。但是因为 const int &ref需要一个 glvalue,目前我们有一个 prvalue,临时物化开始,因此 prvalue 被转换为一个 xvalue。然后引用ref绑定(bind)到这个具体化的 xvalue(因为 xvalue 也是一个 glvalue)而不是绑定(bind)到变量 val直接地。发生这种情况是因为变量的类型 val右边是double而在左侧,我们有一个int的引用强>。但是要将引用绑定(bind)到变量,类型应该匹配。此外,物化临时 xvalue 的生命周期得到延长。

我的问题是:

  1. 根据 C++11 标准,以上哪项解释是正确的。我愿意接受以上解释都不正确,在这种情况下,正确的解释是什么。
  2. 根据 C++17 标准,以上哪项解释是正确的。我愿意接受以上解释都不正确,在这种情况下,正确的解释是什么。
  3. 我也对上述两种可能性的第一步中的纯右值是否实际上是一个临时对象感到困惑?或者 xvalue 是实际对象。我的意思是我们是否有 2 个临时对象,例如第一个是由于“转换为 prvalue”,第二个是由于“prvalue 到 xvalue”转换(临时物质化)。还是我们只有一个临时的,这是由于“prvalue to xvalue”的临时物化。

PS:我不是在寻找解决这个问题的方法。例如,我知道我可以简单地写: const double &ref = val; .我的目标是根据 C++11C++17 标准了解正在发生的事情。

最佳答案

const int &ref = val; 中的

val 是左值,而不是纯右值。即使它被转换为纯右值,这也不意味着在 C++11 或 C++17 中创建一个临时值。在 C++17 中,情况并非如此,因为只有 prvalue-to-xvalue 转换(以及此处不相关的一些特殊情况)会创建一个临时值,而在 C++11 中 [conv.lval]/2说只有类类型的左值到右值转换会创建一个临时对象。

引用的初始化在 [dcl.init.ref] 中解释。

在 C++11 中,根据 [dcl.init.ref]/5.2.2,所有以前的案例都失败了通过初始化表达式的复制初始化创建并初始化目标类型的临时对象,并将引用绑定(bind)到该临时对象。在此复制初始化中,左值 val 被转换为 double 类型的纯右值,然后转换为 int 类型的纯右值,这些步骤都不是创建额外的临时对象。

在 C++17 中,所有情况都会失败,直到 [dcl.init.ref]/5.2.2 ,其中声明初始化表达式首先隐式转换为目标类型的纯右值,这并不意味着创建临时值,然后应用临时物化转换(prvalue-to-xvalue 转换)并将引用绑定(bind)到结果,即指代临时值的 xvalue。

最后总是只有一个临时的,根据 [dcl.init.ref] 中的规则创建的。

https://stackoverflow.com/questions/71806505/

相关文章:

c# - 无法启动程序,访问被拒绝 C# net6.0

c# - 使用 EF Core 按 Id 检索实体的通用方法

javascript - Vue 3 - "Failed to resolve component"

kubernetes - kubectl 等到 pod 消失(终止)

android - 我无法将 Android 项目从 Delphi 10.4 迁移到 Delphi

node.js - 如何在某个日期之前安装 Node 包及其依赖项?

ios - 什么时候在 ios 中选择 serialQueue 而不是并发队列

typescript - 类型错误 : Cannot find module 'firebase-f

c - 你怎么能告诉计算机它正在添加而没有 addl 在程序集中

node.js - Remix.run 不使用 node.js 作为后端吗?