【发布时间】:2021-06-03 01:42:37
【问题描述】:
你好 stackoverflow 社区,
我已经接触 C++ 几个月了,最近我一直在尝试掌握围绕“新”值类别、移动语义,尤其是临时实现的概念。
首先,如何解释“临时物化转换”一词对我来说并不简单。转换部分对我来说很清楚(prvalue -> xvalue)。但是在这种情况下,“临时”究竟是如何定义的呢?我曾经认为临时对象是仅存在的未命名对象 - 从语言的角度来看 - 直到评估它们创建的表达式的最后一步。但这个概念似乎与临时对象实际上似乎不匹配在临时物化、新价值类别等更广泛的背景下。
“临时”一词缺乏明确性导致我无法判断“临时实现”是暂时实现的还是暂时实现的。我猜是前者,但我不确定。另外:“临时”一词是否仅用于类类型?
这直接将我带到了下一个困惑点:prvalues 和 xvalues 在临时变量中扮演什么角色?假设我有一个右值表达式,需要以必须将其转换为 xvalue 的方式进行评估,例如通过执行成员访问。 究竟会发生什么? prvalue 是实际存在的东西(在内存中或其他地方)吗?prvalue 是否已经是临时的?现在,“临时实现转换”描述为“任何完整类型 T 的纯右值都可以转换为相同类型 T 的 xvalue。这种转换通过使用临时对象评估纯右值,从纯右值初始化 T 类型的临时对象作为其结果对象,并在 cppreference.com (https://en.cppreference.com/w/cpp/language/implicit_conversion) 上生成一个表示临时对象的 xvalue 将 prvalue 转换为 xvalue。这个摘录让我认为prvalue是在内存或寄存器中的任何地方都不存在的东西,直到它通过这种转换“实现”。 (另外,我不确定临时对象是否与临时对象相同。)因此,据我了解,这种转换是通过评估具有“真实”对象的纯右值表达式来完成的。然后这个对象由 xvalue 表达式表示(= 表示?)。记忆中发生了什么?右值在哪里,现在在哪里?
我的下一个问题是关于临时实现的某个部分的更具体的问题。在 Kris van Rens 在 YouTube (https://www.youtube.com/watch?v=liAnuOfc66o&t=3576s) 上的演讲“理解 C++ 中的价值类别”中,他展示了这张幻灯片:
根据 cppreference.com 所说的关于临时实现的数字 1 和 2 是明确的情况(1:对类 pravlue 的成员访问,2:绑定对 prvalue 的引用(如在 std::string +operator 中)。
不过,我不太确定数字 3。 Cppreference 说:“请注意,从相同类型的纯右值(通过直接初始化或复制初始化)初始化对象时不会发生临时实现:此类对象直接从初始化程序初始化。这确保了“保证复制省略”。 " + 运算符返回一个纯右值。现在,这个 std::string 类型的纯右值用于初始化一个 auto (也应该解析为 std::string)变量。这听起来像之前的 cppreference 摘录中讨论的情况。那么临时物化真的发生在这里吗?由它们之间的 xvalue 表达式“表示”的对象(1 和 2)会发生什么?他们什么时候被摧毁?如果 + 运算符返回一个纯右值,它甚至“存在”于某处吗?如果纯右值甚至不是真正的(物化的?)对象,对象 auto x “直接从初始化程序”(纯右值)如何初始化?
在大约 40:00 在 YouTube (https://www.youtube.com/watch?v=-dc5vqt2tgA&t=2557s) 上的演讲“没有什么比复制或移动更好 - Roger Orr [ACCU 2018]”中,几乎有相同的例子:
这张幻灯片甚至说在初始化变量时会发生临时实现,这明显与上面的 cppference 异常相矛盾。那么什么是真的呢?
如您所见,我对整个主题感到很困惑。对我来说,掌握这些概念尤其困难,因为我在网上找不到以统一方式使用的各种术语的任何明确定义。非常感谢任何帮助!
最好的问候, 鲁珀尔特
TL;DR:什么是临时实现转换上下文中的临时?这是否意味着一个临时的物化了,或者它是暂时的物化?也是临时的 = 临时对象?
在幻灯片中,3(第一张幻灯片)和 1(第二张幻灯片)是否真的是发生临时实现的点(与 cppreference 所说的从相同类型的 pravlues 初始化的内容相冲突)?
【问题讨论】:
标签: temporary-objects value-categories