这个问题很好,因为它有关于rvalue
, lvalue
, xvalue
, glvalue
, 和 prvalue
的区别的答案。排名第一的答案对每一个都有很好的解释,我在阅读时理解了它们的区别。然而,我很难记住它们的区别,并且每次有人使用这些术语时,我都需要通过谷歌来提醒自己哪个是哪个。
是否有任何常见的提示或其他方式让人记住哪个是哪个? 我真的想能够在我的脑海中清晰记住它们,而不像我目前那样混淆它们。
这个问题很好,因为它有关于rvalue
, lvalue
, xvalue
, glvalue
, 和 prvalue
的区别的答案。排名第一的答案对每一个都有很好的解释,我在阅读时理解了它们的区别。然而,我很难记住它们的区别,并且每次有人使用这些术语时,我都需要通过谷歌来提醒自己哪个是哪个。
是否有任何常见的提示或其他方式让人记住哪个是哪个? 我真的想能够在我的脑海中清晰记住它们,而不像我目前那样混淆它们。
我做了两个关联:
std::move
表达式的内容如果不是这两种情况,则可能是prvalue。
现在,为了记住glvalues和rvalues,我简单地想象了这个图:
lvalues和xvalues都是glvalues,而xvalues和prvalues都是rvalues。这实际上是你需要知道的全部内容。
也许一个助记符可以帮助记住lvaluse、xvalues和prvalues,放在底部的单词是Lower eXPRessions
(它包含L、X和PR)。也可能不需要。
在编程中,lvalue 可以被视为“命名”的变量或内存位置... rvalue 可以被视为“未命名”的内存位置(即从函数返回的临时变量)或纯“值”(例如数字)。
std::map<std::string, int> m;
,那么 m["test"]
的名称是什么? - Ben Voigtm
上的operator[]
进行索引。例如,int foo() { return 5; }
的返回值的“名称”是什么?那就是“未命名”的例子。但在你的情况下,你是通过一个命名的对象实例来访问内存位置,因此它是一个左值。 - Jasonstd::vector<double> v(10);
,v.begin()
没有名称,但是 *v.begin()
有名称吗? - Ben Voigtv.begin()
并没有真正地从向量中返回一个对象,而是返回一个“指针”(即迭代器)。另一方面,*v.begin()
实际上确实返回向量中的对象。所以我想这就是一个例子,你可以说一个rvalue在使用我的简单规则时有一个“名称”,打破了这个系统,但值得一提的是,在大多数情况下,这个思想的简单性都是适用的。 - Jason