C++ 为什么删除的复制构造函数不';不允许使用其他多态类型的构造函数?

C++ 为什么删除的复制构造函数不';不允许使用其他多态类型的构造函数?,c++,polymorphism,copy-constructor,deleted-functions,C++,Polymorphism,Copy Constructor,Deleted Functions,我想知道为什么这个程序不编译(在msvc、gcc和clang上的行为相同): #包括 使用名称空间std; 结构动作 { 虚拟无效操作() { cout删除函数不会将其从重载解析中删除。该函数仅定义为已删除。其目的是在重载解析选择该函数时使程序格式错误 因为复制c'tor比您提供的特殊基类c'tor更匹配,所以如果您不强制转换,重载解析将始终选择它 如何最好地处理它是有争议的。从理论上讲,你可以让复制者做类似的包装。然而,我为有一个不复制的复制者而苦恼。你的百万可能会非常痛苦 另一个我个人更喜欢

我想知道为什么这个程序不编译(在msvc、gcc和clang上的行为相同):

#包括
使用名称空间std;
结构动作
{
虚拟无效操作()
{

cout删除函数不会将其从重载解析中删除。该函数仅定义为已删除。其目的是在重载解析选择该函数时使程序格式错误

因为复制c'tor比您提供的特殊基类c'tor更匹配,所以如果您不强制转换,重载解析将始终选择它

如何最好地处理它是有争议的。从理论上讲,你可以让复制者做类似的包装。然而,我为有一个不复制的复制者而苦恼。你的百万可能会非常痛苦

另一个我个人更喜欢的选择是,不按原样提供公共构造函数。相反,让客户机通过常规命名函数创建装饰器。类似如下:

ActionDecorator decorate(Action& action) {
  return {action};
}

现在,该类可以真正保持不可复制,并且客户端永远不需要把它自己投射出来。如果他们通过<代码> ActudioDoCaltudio< /COD> > <代码>装饰> /COD>,在构建实例之前,它将绑定到<代码>动作< /代码>引用。因此,它甚至不考虑拷贝ctoor。


类必须是可移动的,这样才能在C++17之前工作。

默认的移动构造函数或赋值运算符(15.8)定义为“已删除”的函数在所有上下文中都从候选函数集中排除。@Yola-这不是默认值,而是已删除。这是一个重要的区别。@Yola-而且,这不是移动操作,而是复制操作。您不能以任何方式将它们从重载集中排除。谢谢,您是对的。您知道为什么要删除它们吗函数没有从重载解析中删除?我想知道它会暗示什么问题(我假设有一些问题,因为它不是以这种方式实现的)。@Piotrek-您自己的用例就是一个例子。如果某个东西看起来像一个副本,但实际上不是副本,那就太糟糕了(我觉得不舒服)。删除函数的目的是在编译时最终发出信号,表明客户端正在尝试一个无效的操作,而不是静默地执行其他操作。唯一的例外是隐式删除移动操作(以便不破坏遗留代码)。恐怕这是我们必须玩的玩具。
ActionDecorator decorate(Action& action) {
  return {action};
}