问题描述
我有两个类(称它们为 base
和 derived
),它们具有一组不常见的语义:
-
base
是derived
的父级,如您所料 -
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 &&)
。由于 derived
是 base
中的不完整类型,因此我必须进行外部操作,但这有效:
#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();
}