我试图编写一个包含返回其中一个类成员的函数的类,并且我希望允许调用者移动或复制返回的值。我写了一些虚拟结构来测试这个;在尝试不同的变化之后,这似乎给了我想要的东西。
#include <iostream>
using namespace std;
struct S {
int x;
S() : x(10) { cout << "ctor called\n"; }
S(const S& s) : x(s.x) { cout << "copy ctor called\n"; }
S(S&& s) : x(s.x) { cout << "move ctor called\n"; }
// I'm implementing move and copy the same way since x is an int.
// I just want to know which one gets called.
};
struct T {
S s;
T() : s() {}
S&& Test() && {
return move(s);
}
const S& Test() & {
return s;
}
};
int main() {
T t;
auto v = move(t).Test();
cout << v.x << "\n";
T t2;
auto w = t2.Test();
cout << w.x << "\n";
return 0;
}
代码打印出来(使用clang ++ - 5.0 c ++ 14):
ctor called
move ctor called
10
ctor called
copy ctor called
10
这是实现我想要的可接受的方式吗?我有几个问题:
在第一个测试函数中,我尝试了S&&
和S
作为返回类型,并且它不会更改输出。 &&
是否表示(非模板)返回类型的任何内容?
是否保证auto v = move(t).Test()
只会使&#34;移动&#34;会员?如果struct T
有其他成员变量,我可以假设这个调用不会使它们失效吗?
答案 0 :(得分:3)
在第一个Test函数中,我为返回类型尝试了
S&&
和S
,并且它不会更改输出。&&
是否表示(非模板)返回类型的任何内容?
差别不大:
S&&
是(r值)引用,因此对象尚未移动。S
将移动构造S
,因此一旦调用该方法,就会移动成员。对于move(t).Test();
,返回S&&
不执行任何操作,而返回S
会移动该成员。
是否保证auto v = move(t).Test()只会使“移动”成员无效?如果struct T有其他成员变量,我可以假设这个调用不会使它们失效吗?
是的,只移动了T::s
。 std::move
只是rvalue
的演员。
答案 1 :(得分:1)
是的,这是实现这一点的可接受方式。