c ++:为什么要调用foo(X&)而不是foo(X&&)?

时间:2016-09-01 01:41:07

标签: c++ rvalue

这里,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&)
}

2 个答案:

答案 0 :(得分:3)

creator()返回一个指针。

取消引用该指针会获得左值。指针解引用会产生左值。毕竟,如果p是指针,您可以为其分配:*p=some_value,并且您只能分配左值,因此它必须是左值。

你对两件事情感到困惑。确实,该函数返回一个右值。但是你没有传递函数返回的内容。该函数返回一个指针,你正在取消引用指针,这会产生一个左值。

答案 1 :(得分:3)

从身份和可动性的角度思考问题是有帮助的:

  • 有身份,不能被移走?左值
  • 有身份,可以搬走吗? x值
  • 没有身份? prvalue

取消引用指针会产生一个具有身份的表达式,该表达式无法移动,因此它是一个左值。因此,它匹配X&重载。

如果要调用另一个重载,则必须对表达式进行注释以指示可以安全地移动它。这是std::move的用途。一旦你这样做,表达式就变成了一个xvalue,现在匹配X&&重载。