普通右值引用和 std::forward 返回的右值引用有什么区别?
What's the difference between an ordinary rvalue reference and one returned by std::forward?
我做不到:
int &&q = 7;
int &&r = q;
//Error Message:
//cannot convert from 'int' to 'int &&'
//You cannot bind an lvalue to an rvalue reference
如果我没理解错的话,在初始化右值引用时,也会初始化一个临时变量。所以 int &&q = 7;
可以认为是:
int temp = 7;
int &&q = temp;
而且在右侧使用reference的时候,我其实是在使用referee。所以int &&r = q;
可以认为是:
int &&r = temp; //bind an lvalue to an rvalue reference, cause error, understandable
以上是我理解的编译错误发生的方式。
为什么加上std::forward
可以解决这个问题?
int &&q = 7;
int &&r = std::forward<int>(q);
我知道 std::forward
总是 returns 右值引用,std::forward
返回的引用与 int&&q
有何不同?
how is the reference returned by std::forward
different from int&&q
?
他们的value categories不一样。并注意类型和值类别是不同的东西。
q
是一个命名变量,它被限定为lvalue,所以它不能绑定到右值引用。
(强调我的)
the name of a variable, a function, a template parameter object (since C++20), or a data member, regardless of type, such as std::cin
or std::endl
. Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression;
虽然从函数返回的右值引用被限定为 xvalue, which belongs to rvalue。
a function call or an overloaded operator expression, whose return type is rvalue reference to object, such as std::move(x)
;
表达式q
和std::forward<int>(q)
的区别在于前者是左值,后者是右值(基本类别xvalue)。
我在 中解决了类似的问题:要点是 q
作为表达式是一个 左值 ,因为它有一个名称。 std::forward<int>(q)
(或等效的 std::move(q)
)是没有名称的表达式,并且由于它们 return(未命名)右值引用,它们是 xvalues,它是 rvalue 的子类别并且可以因此绑定到右值引用。
我做不到:
int &&q = 7;
int &&r = q;
//Error Message:
//cannot convert from 'int' to 'int &&'
//You cannot bind an lvalue to an rvalue reference
如果我没理解错的话,在初始化右值引用时,也会初始化一个临时变量。所以 int &&q = 7;
可以认为是:
int temp = 7;
int &&q = temp;
而且在右侧使用reference的时候,我其实是在使用referee。所以int &&r = q;
可以认为是:
int &&r = temp; //bind an lvalue to an rvalue reference, cause error, understandable
以上是我理解的编译错误发生的方式。
为什么加上std::forward
可以解决这个问题?
int &&q = 7;
int &&r = std::forward<int>(q);
我知道 std::forward
总是 returns 右值引用,std::forward
返回的引用与 int&&q
有何不同?
how is the reference returned by
std::forward
different fromint&&q
?
他们的value categories不一样。并注意类型和值类别是不同的东西。
q
是一个命名变量,它被限定为lvalue,所以它不能绑定到右值引用。
(强调我的)
the name of a variable, a function, a template parameter object (since C++20), or a data member, regardless of type, such as
std::cin
orstd::endl
. Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression;
虽然从函数返回的右值引用被限定为 xvalue, which belongs to rvalue。
a function call or an overloaded operator expression, whose return type is rvalue reference to object, such as
std::move(x)
;
表达式q
和std::forward<int>(q)
的区别在于前者是左值,后者是右值(基本类别xvalue)。
我在 q
作为表达式是一个 左值 ,因为它有一个名称。 std::forward<int>(q)
(或等效的 std::move(q)
)是没有名称的表达式,并且由于它们 return(未命名)右值引用,它们是 xvalues,它是 rvalue 的子类别并且可以因此绑定到右值引用。