我以为我已经设法完全理解(在其他 SO 问题的帮助下,谢谢)C++17 关于值类别的更改,但现在我注意到这个问题,这表明我并不真正理解它们。
在 C++11 中,对值类别有“具有同一性/可以从其中移动”的解释,并且“同一性”含义的定义仍然存在于参考参数 https://en.cppreference.com/w/cpp/language/value_category:
具有同一性:可以确定表达式是否与另一个表达式引用相同的实体,例如通过比较对象的地址或它们标识的函数(直接或间接获得)。
在C++17中,“具有同一性/可以从其中移动”不再成立,但新的定义也是基于“同一性”的概念:
左值(“广义”左值)是一个表达式,其计算确定对象、位域或函数的身份;
我的问题/误解是:这是“身份”的相同含义,还是不同的“身份”?按照我的理解,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 中临时对象是纯右值。所以我假设我可以将 A&& 绑定到它(其中,像任何左值一样,我可以获取一个地址,但只能在一个单独的表达式中)这一事实不足以得出结论:它的评估决定了一个身份(毕竟,无论发生什么“&r;”行不是我原始表达式求值的一部分),但在 c++17 中,在我看来这将是唯一可能的解释?
您能帮我确定我写的哪一部分是错误的吗?或者这是正确的,答案只是“身份”这个词改变了它的含义?