几个星期以来,我一直在仔细研究右值和右值引用。我越来越有信心,我对理解以下之间的区别有了一些清晰的认识:
- 定义变量或函数参数的类型(即
int x;
vs.int && x = …;
- 表达式的表达式类别,包括那些可能使用先前定义的参数的表达式(即,给定函数定义
A&& foo()
,并且给定一个仅由 组成的表达式foo()
,表达式类别是“xvalue”) - 当子表达式在包含表达式中使用时,子表达式求值结果的类型(
foo
即,给定相同的定义,在包含表达式中使用时子表达式的类型是foo()
(A
notA&&
))。
我的问题是关于xvalue表达式和prvalue表达式之间的区别(这两个表达式类别都是右值)。
鉴于:
class A
{};
A&& foo() {…}
A goo() {…}
void test(A&& a) {…}
int main()
{
test(foo()); // test() called with xvalue expression
test(goo()); // test() called with prvalue expression
}
请注意,test()
使用 xvalue 表达式和 prvalue 表达式成功调用了该函数。(如果我对此有误解,请纠正我。)
我的问题是:由于函数参数成功绑定到A&& a
xvalues和prvalues , xvalues 和 prvalues 在重载决议方面的实际区别是什么?test
是否存在表达式的 xvalue/prvalue 特性导致不同的函数重载分辨率的场景示例?还是 xvalues 和 rvalues 之间的区别仅与语言的其他方面相关,与函数重载决议无关(例如,decltype
(即,参见什么是 decltype(0 + 0)? ))?