【问题标题】:Move constructor and assignment operator: why no default for derived classes?移动构造函数和赋值运算符:为什么派生类没有默认值?
【发布时间】:2010-04-22 20:39:49
【问题描述】:

为什么没有为派生类创建默认的移动构造函数或赋值运算符?证明我的意思;有这个设置代码:

#include <utility>

struct A
{
  A () { }
  A (A&&) { throw 0; }
  A& operator= (A&&) { throw 0; }
};

struct B : A
{ };

以下任一行抛出:

A  x (std::move (A ());
A  x;  x = A ();

但以下都不是:

B  x (std::move (B ());
B  x;  x = B ();

以防万一,我使用 GCC 4.4 进行了测试。

编辑:后来使用 GCC 4.5 进行的测试显示了相同的行为。

【问题讨论】:

  • std::move 在这里有什么改变吗? A() 不是已经是右值了吗?
  • 是的,确实如此。否则,C++ 标准允许编译器将其压缩为 just-construct-x(或者我在 freenode.net 上被告知)。我还验证了如果没有std::move,移动构造函数不会被触发,所以 freenode.net 的评论似乎是正确的。
  • @Mike: Copy elision (12.8/34, 0x FCD) 是一种常见的优化,但是使用 move() 会使这个表达式超出允许的范围。
  • 啊,是的,你是对的!因此,从某种意义上说,移动 ctor 需要可访问,它仍然是一个移动,但实际调用被省略了,就像对复制 ctor 的调用一样。感谢您的澄清!

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


【解决方案1】:

读取 0x FCD 中的 12.8(特别是对于移动 ctor 的 12.8/17),这似乎是一个 GCC 错误。我看到在 4.5 中发生的事情与在 4.4 中发生的一样。

我可能遗漏了有关已删除函数的特殊情况或类似情况,但我还没有看到任何迹象。

【讨论】:

  • 刚刚用 4.5 测试过,我得到了相同的结果。您可以在任何其他编译器上进行测试吗? (鉴于 C++0x 还没有完成,顺便说一句,它可能不是错误,而是过时的行为。)
  • gcc 尚不支持 12.8 中的一堆东西(源自 N3053),根据他们的C++0x support page - 这可能是问题吗?
  • @douplep:如果目标是支持 0x FCD 所说的,那么即使它源于过时的行为也是一个错误。 :)
  • @Roger:是的,你可能是对的。如果有人可以验证默认移动构造函数/赋值是否已隐式添加到任何其他编译器上,我想我们可以确定您的答案。
  • @Roger:原来我有一个过时的草稿,所以我不太明白你的答案。在阅读了您在当前草案中提到的条款后,就很清楚了。谢谢。
猜你喜欢
  • 1970-01-01
  • 2013-03-16
  • 1970-01-01
  • 2017-05-15
  • 1970-01-01
  • 2016-05-19
  • 2014-05-16
  • 1970-01-01
  • 2016-09-13
相关资源
最近更新 更多