【问题标题】:Can move constructor take arguments other than the class itself?移动构造函数可以接受类本身以外的参数吗?
【发布时间】:2017-09-14 19:49:18
【问题描述】:

基本上,移动构造函数的参数就是类本身。

但是,如果我想从左值构造类的对象而不进行复制操作,我可以这样做吗?

class A{
   A(const LargeDataType& inData):data(inData) {} // constructor 1
   A(LargeDataType&& inData):data(std::move(inData)) {} // constructor 2
   private:
        LargeDataType data;
};

使用它:

方法一:

LargeDataType outData = 100;
A objA(std::move(outData)); // call constructor 2

方法2(如果没有实现构造函数2):

LargeDataType outData = 100;
A objA(std::move(outData)); // call constructor 1

这样构造objA的时候就没有拷贝操作了。我的问题是:

  1. 这样创建移动构造函数是否合法?

  2. 这比传统构造函数更高效,因为在创建 objA 期间不需要复制?

  3. 方法2是否能比方法1更好,效率也一样?

非常感谢!

【问题讨论】:

  • 这些恶作剧并不能避免任何复制,因为“移动”和int 与复制它是一样的。
  • int 没有移动构造函数或任何移动操作,所以这一切都只是副本......
  • 对于int,它并不是很有用,但可能对std::stringstd::vector 有用。
  • @Jarod42 是的,这只是一个例子,我想将它用于更复杂的数据类型
  • 您当然可以编写这样的构造函数,这样做甚至可以带来好处。但它不是移动构造函数。

标签: c++ visual-studio c++11 move-semantics move-constructor


【解决方案1】:

你所拥有的不是移动构造函数。它只是一个将右值引用作为参数的构造函数。它们是非常好的构造函数,但它们不是移动构造函数。

来自 C++11 标准 (12.8/3):

X的非模板构造函数是一个移动构造函数,如果它的第一个参数是X&&const X&&volatile X&&const volatile X&&类型,并且要么没有其他参数,要么没有其他参数所有其他参数都有默认参数 (8.3.6)。

只有

A(A&& a) { ... }
A(const A&& a) { ... }
A(volatile A&& a) { ... }
A(volatile const A&& a) { ... }

可能称为移动构造函数。

如果除了上述参数之外,您还有具有默认值的参数,它们也可以作为移动构造函数。例如

A(A&& a, T arg = {}) { ... }

【讨论】:

  • 移动构造函数的签名可以比您的示例中的签名多。
  • A(const A&&) 也将是一个移动构造函数;-)
  • A(volatile A&&)
  • 仍然不完整:) A(A&&, T = {}) 等等也将是移动构造函数。附加参数必须都具有默认参数。
  • 纯口语,有时人们称Foo(Bar&&);为“转换移动构造函数”。语言律师无疑会指出,该术语没有多大意义。
猜你喜欢
  • 2020-02-09
  • 2012-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-08
  • 2012-03-08
相关资源
最近更新 更多