微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我可以使基类移动构造函数重载优于派生类复制构造函数吗?

如何解决我可以使基类移动构造函数重载优于派生类复制构造函数吗?

我有两个类(称它们为 basederived),它们具有一组不常见的语义:

  • basederived 的父级,如您所料
  • base 是可复制和可移动的
  • derived 可移动但不可复制
  • base 不能从 derived
  • 复制构造

这一切都非常简单。不过,我希望 base 可以从 derived 移动构造,因此我可以执行以下操作:

derived d;
base b(std::move(d));

我试图表达这一点如下:

#include <utility>

struct derived;

struct base
{
    base() { }
    base(const derived &) = delete;
    base(const base &) { }
    base(base &&) { }
};

struct derived : base 
{ 
    derived() { }
    derived(const derived &) = delete;
    derived(derived &&) = default;
};

base func()
{
    derived d;
    return std::move(d);
}

int main()
{
    func();
}

(我知道在一个真实的例子中我也应该包括赋值运算符,为了简洁起见省略了它们)

然而,上面的fails to compile

<source>: In function 'base func()':
<source>:23:23: error: use of deleted function 'base::base(const derived&)'
   23 |     return std::move(d);
      |                       ^
<source>:8:5: note: declared here
    8 |     base(const derived &) = delete;
      |     ^~~~
ASM generation compiler returned: 1
<source>: In function 'base func()':
<source>:23:23: error: use of deleted function 'base::base(const derived&)'
   23 |     return std::move(d);
      |                       ^
<source>:8:5: note: declared here
    8 |     base(const derived &) = delete;
      |     ^~~~

编译器更喜欢从 base 删除 const derived & 的构造函数。我的意图是 std::move(d) 类型的表达式 derived && 将改为调用 base 的移动构造函数

有没有办法做到这一点?

解决方法

如上面@M.M 的评论所示,解决方案是显式提供构造函数 base(derived &&)。由于 derivedbase 中的不完整类型,因此我必须进行外部操作,但这有效:

#include <utility>

struct derived;

struct base
{
    base() { }
    base(const derived &) = delete;
    base(base &&) { }
    base(derived &&);
};

struct derived : base 
{ 
    derived() { }
    derived(const derived &) = delete;
    derived(derived &&) = default;
};

base::base(derived &&d) : 
    base(static_cast<base &&>(d)) { }

base func()
{
    derived d;
    return std::move(d);
}

int main()
{
    func();
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。