允许移动和复制返回的类成员

时间:2018-02-20 10:09:03

标签: c++ c++14

我试图编写一个包含返回其中一个类成员的函数的类,并且我希望允许调用者移动或复制返回的值。我写了一些虚拟结构来测试这个;在尝试不同的变化之后,这似乎给了我想要的东西。

#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

这是实现我想要的可接受的方式吗?我有几个问题:

  1. 在第一个测试函数中,我尝试了S&&S作为返回类型,并且它不会更改输出。 &&是否表示(非模板)返回类型的任何内容?

  2. 是否保证auto v = move(t).Test()只会使&#34;移动&#34;会员?如果struct T有其他成员变量,我可以假设这个调用不会使它们失效吗?

2 个答案:

答案 0 :(得分:3)

  

在第一个Test函数中,我为返回类型尝试了S&&S,并且它不会更改输出。 &&是否表示(非模板)返回类型的任何内容?

差别不大:

  • S&&是(r值)引用,因此对象尚未移动。
  • 返回S将移动构造S,因此一旦调用该方法,就会移动成员。

对于move(t).Test();,返回S&&不执行任何操作,而返回S会移动该成员。

  

是否保证auto v = move(t).Test()只会使“移动”成员无效?如果struct T有其他成员变量,我可以假设这个调用不会使它们失效吗?

是的,只移动了T::sstd::move只是rvalue的演员。

答案 1 :(得分:1)

是的,这是实现这一点的可接受方式。

  1. 它做同样的事情,因为返回的值是临时对象,因此是rvalue。
  2. 取决于您的意思是无效