【问题标题】:Why is `T(const T&&)` called a move constructor?为什么`T(const T&&)`被称为移动构造函数?
【发布时间】:2014-06-30 10:28:08
【问题描述】:

[C++11: 12.8/3]: class X 的非模板构造函数是移动构造函数,如果它的第一个参数是 typeX&&const X&&volatile X&&const volatile X&&,并且要么没有其他参数,要么否则所有其他参数都有默认参数(8.3.6)。 [..]

为什么采用const 右值引用的构造函数被标准称为“移动构造函数”?除了最边缘的情况外,肯定是it's self-evidentthis prohibits meaningful move semantics

“根据我的说法”,正如 SO 所说,T(const T&&) 不应被视为“移动构造函数”,因为it's basically useless

如果任何东西,不应该叫拷贝构造函数吗?

【问题讨论】:

  • “移动构造函数”可以撕掉mutable 胆量,不是吗? ;)
  • 我的猜测是,如果你有一个采用const X&& 的构造函数,那么你的类可能有一些不寻常的语义,隐式定义一个“真正的”移动构造函数是没有意义的。所以我们只是说const X&& 构造函数是一个移动构造函数。你怎么称呼它并不重要(我认为)。
  • @LightnessRacesinOrbit:等等,所以你认为 copy 构造函数移动 mutable合理另一个const 对象的胆量?
  • 那么复制构造函数如何能够响应@FredOverflow 的评论呢?
  • 这不就是最不意外的原则吗?该构造是否真的有用似乎并不那么有趣。

标签: c++ c++11 move-semantics


【解决方案1】:

以下是移动构造函数和其他构造函数的一些区别:

  • 可以默认移动构造函数
  • 移动构造函数不会阻止类型成为“文字类型”
  • 非平凡的移动构造函数阻止一个类型成为“平凡的可复制类型”
  • 移动构造函数阻止生成隐式移动构造函数
  • 标准库函数可以自动调用移动构造函数

据我所知,对于所有这些,不调用 X(const X &&) 移动构造函数会产生不良结果。

您提供了一个替代方案:它可能被称为复制构造函数。这似乎也有不良结果:它会抑制隐式复制构造函数。

移动构造函数是否真正移动并不重要。 POD 类型也可能有一个移动构造函数。它只是制作一个副本,但它仍然被称为移动构造函数。

【讨论】:

  • 是的,你已经说过了!我在问为什么那些是不可取的。如果X(const X&&) 未能阻止X(X&&) 的生成是特别不可取的呢?
  • @LightnessRacesinOrbit 这不是你问的,但我应该猜到这就是你的意思,抱歉。如果您作为程序员定义了X(const X &&) 构造函数但没有定义X(X &&) 构造函数,那么您不想要X(X &&) 构造函数的可能性要大得多。而且编译器通常不应该默默地做程序员可能不想要的事情。
  • @LightnessRacesinOrbit 另外一点:能够定义X(const X &&) = default; 的优势与能够定义X(X &&) = default; 的优势相同。将具有非平凡X(const X &&) 构造函数的类型标记为可平凡复制(可通过类型特征检查)可能会破坏针对可平凡复制类型优化的标准库函数。
  • 好吧,至少它与 std::move 的粗俗命名是一致的。该标准似乎使用“复制”来表示“与左值值/引用有关的事情”,而使用“移动”来表示“与右值引用有关的事情”,这很愚蠢。
  • @LightnessRacesinOrbit 对,如果您愿意,可以将“复制构造函数”读作“左值复制构造函数”,将“移动构造函数”读作“右值复制构造函数”,如果您愿意,标准可能会更清晰一些这就是它所说的构造函数。再说一次,X(const X &) 构造函数也可以用右值调用。我认为没有一个完美的名称可以准确地捕捉预期的语义和实现细节,但足够简洁,标准可以在整个过程中使用该名称。
猜你喜欢
  • 2011-05-17
  • 1970-01-01
  • 2018-02-10
  • 1970-01-01
  • 2018-03-03
  • 2012-08-02
  • 2012-01-21
  • 2021-11-05
  • 1970-01-01
相关资源
最近更新 更多