当显式声明返回类型rvalue vs no ref时,行为是否存在差异?根据下面的例子,似乎没有任何区别。
#include <iostream>
#include <vector>
using namespace std;
struct A {
A(int x) : x_(x) {}
A(A&&) = default; // VC12 hasn't implemented default move
A(const A&) = delete;
A& operator=(A&&) = default;
A& operator=(const A&) = delete;
vector<int> x_;
};
struct B{
B(int x) : a_(x) {}
A&& foo1() { return move(a_); } // explicitly declared as rvalue
A foo2() { return move(a_); } // no ref
A a_;
};
int main() {
B b1(7);
A a1 = b1.foo1();
B b2(7);
A a2 = b2.foo2();
cout << a1.x_.size() << ' ' << a2.x_.size() << endl;
cout << b1.a_.x_.size() << ' ' << b2.a_.x_.size() << endl;
return 0;
}
此示例由Ideone的C ++ 14编译器编译(不确定确切版本,我怀疑它是gnu 5.1)和VC12(Visual Studio 2013)。唯一的微小差异是VC12需要一个明确的移动实现。
编辑:A related SO post说这两个函数最终做同样的事情。但是,“在很多情况下,它允许编译器执行复制省略并忽略对返回类型的移动构造函数的调用,如C ++ 11标准的第12.8 / 31节所允许的那样”。 “复制省略允许编译器直接在对象中创建函数的返回值。”
问题1:当明确调用move时,仍然会发生复制省略,对吗?
问题2: 当在左值上明确调用move(因此需要调用)时,A&amp;&amp;和A意味着相同的行为。当未明确调用move时,意味着编译器执行复制省略,A应该是唯一的返回类型。结合上面的两个场景,我可以得出结论返回类型A&amp;&amp;没有用,只会增加混乱?
答案 0 :(得分:2)
使用
A&& foo1() { return move(a_); }
A foo2() { return move(a_); }
foo1
返回(右值)参考。foo2
使用移动构造函数构造一个对象A
。