我以为我已经设法完全理解了C ++ 17在值类别方面的变化(在其他SO问题的帮助下,谢谢),但是现在我注意到了这个问题,这表明我不太了解它们。
在C ++ 11中,对值类别有“具有身份/可以从中移出”的解释,并且cppreference中仍然存在“身份”的含义的定义:
具有身份:可以通过比较对象的地址或它们标识的功能(直接或间接获得)来确定该表达式是否与另一个表达式引用相同的实体。
在C ++ 17中,“具有身份/可以从中移出”不再成立,但是新定义也基于“身份”的概念:
glvalue(“广义” lvalue)是一个表达式,其求值确定对象,位字段或函数的身份;
我的问题/误解是:这是“身份”的同一意思,还是不同的“身份”?据我了解,c ++ 17中的情况如下:
A f() { return A(); }
A a = f(); // 1: f() is a prvalue expression, used to directly initialize a.
f(); // 2: f() is a prvalue expr., converted to xvalue by temporary materialization
A&& r = f(); // 3: f() is a prvalue expr., converted to xvalue by temporary materialization
在第二和第三种情况下,我获得一个xvalue,这意味着它应该具有一个标识。因此,我应该能够 得到它的地址 [编辑:]我应该能够确定它是否与其他表达式所引用的实体相同,但是我认为我不能。当然,在第三种情况下,我可以将“&r”作为单独的命令执行,然后将其地址与另一个表达式的地址进行比较,但这是因为A &&是左值。是通过A &&取得地址,在这种情况下,“直接或间接获得”是什么意思?我认为这不是正确的答案,因为在C ++ 11中,我也可以轻松地做到
A&& r = f(); // 4: f() is a prvalue expression. Temporary materialization does
// not happen, the temporary (prvalue) gets its lifetime
// extended to match the lifetime of the reference
&r;
尽管r所引用的对象的生命周期延长了,但它仍然是一个临时对象,并且在c ++ 11中,临时对象是prvalues。因此,我假设我可以将A &&绑定到该事实(与任何左值一样,我可以接受一个地址,但只能在一个单独的表达式中)不足以得出其评估确定身份的结论(毕竟,无论发生什么情况, “&r;”行不是我的原始表达式求值的一部分),但是在c ++ 17中,它看起来像是唯一可能的解释?
您能通过确定我写的哪一部分不正确来帮助我吗?还是正确的,答案仅仅是“身份”一词改变了其含义?
为什么您认为C ++ 11概念不再适用?该页面说该版本引入了“具有身份”的想法,而不是它是唯一使用它的版本。C ++ 17所做的是说prvalues“等到”它们用于对象的初始化,从而完全成为对象。(因此,它将“成为对象”与“具有身份”合并在一起,这比较简单;显然,每个对象都可以this
被检测到。)
真正的意思是该目标对象的地址被无形地传递到prvalue构造的位置,以便从头开始将其显示在正确的位置。编译器已经以RVO的名称进行了此操作,但是更改保证了这一点,并删除了正式的可移动性限制。
xvalue肯定具有一个标识:如果通过(两种)引用将prvalue传递给函数,则它可以使用其地址。它甚至可以返回它,以便(在相同的全表达式期间)创建它的函数可以使用其地址。禁止采用临时住址是一项单独的安全措施,即使在(例如)static_cast<A&&>(get_a())
用于强迫临时实现后也适用。(但是,它不能阻止您获取glvalue的地址,该glvalue引用了另一个函数返回的临时值。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句