为什么该程序调用复制构造函数而不是move构造函数?

class Qwe {
public:
    int x=0;
    Qwe(int x) : x(x){}
    Qwe(const Qwe& q) {
        cout<<"copy ctor\n";
    }
    Qwe(Qwe&& q) {
        cout<<"move ctor\n";
    }
};

Qwe foo(int x) {
    Qwe q=42;
    Qwe e=32;
    cout<<"return!!!\n";
    return q.x > x ? q : e;
}

int main(void)
{
    Qwe r = foo(50);
}

结果是:

return!!!
copy ctor
return q.x > x ? q : e;用于禁用nrvo。当我将其包装在std::move中时,它确实被移动了。但是在“C++之旅”中,作者说,必须在调用move时调用它。

我做错了什么?

最佳答案

您没有以允许复制/移动省略的方式编写函数。用移动替换副本的要求如下:

[class.copy.elision]/3:



上面的内容来自C++ 17,但是C++ 11的措辞几乎相同。条件运算符不是,它是在函数范围内命名对象的id表达式。

在特定情况下,id表达式类似于qe。您需要在该范围内命名一个对象。条件表达式不符合命名对象的条件,因此它必须执行一个副本。

如果您想在困难的文字墙上锻炼英语理解能力,那么这就是用C++ 11编写的方式。花费一些精力来查看IMO,但与上面的澄清版本相同:

10-08 19:52