这里,creator()返回一个指向X的指针,我将其取消引用并传递给foo。既然这是一个左值,那么应该使用移动语义,对吧?但是当我运行它时,我发现foo(X&)被调用了。
#include <iostream>
using namespace std;
struct X {
int i;
};
void foo(X& x) {
cout << "foo(X&)" << endl;
}
void foo(X&& x) {
cout << "foo(X&&)" << endl;
}
struct X* creator() {
return new X {5};
}
main() {
X x{5};
foo(*creator()); // prints foo(X&)
}
答案 0 :(得分:3)
creator()
返回一个指针。
取消引用该指针会获得左值。指针解引用会产生左值。毕竟,如果p
是指针,您可以为其分配:*p=some_value
,并且您只能分配左值,因此它必须是左值。
你对两件事情感到困惑。确实,该函数返回一个右值。但是你没有传递函数返回的内容。该函数返回一个指针,你正在取消引用指针,这会产生一个左值。
答案 1 :(得分:3)
从身份和可动性的角度思考问题是有帮助的:
取消引用指针会产生一个具有身份的表达式,该表达式无法移动,因此它是一个左值。因此,它匹配X&
重载。
如果要调用另一个重载,则必须对表达式进行注释以指示可以安全地移动它。这是std::move
的用途。一旦你这样做,表达式就变成了一个xvalue,现在匹配X&&
重载。