错误: 使用已删除函数

我一直在研究一个朋友写的一些 C + + 代码,在用 gcc4.6编译代码时,我得到了以下我从未见过的错误:

error: use of deleted function


‘GameFSM_<std::array<C, 2ul> >::hdealt::hdealt()’ is implicitly deleted because the default definition would be ill-formed:
uninitialized non-static const member ‘const h_t FlopPokerGameFSM_<std::array<C, 2ul> >::hdealt::h’

编辑: 这来自使用升级 MSM: 提升网页的部分代码

编辑2: 在源代码的任何地方都没有使用 = delete()

一般来说,这个错误意味着什么? 当这种类型的错误发生时,我应该寻找什么?

312518 次浏览

您正在使用一个标记为 deleted的函数。
例如:

int doSomething( int ) = delete;

删除是 C + + 0x 的一个新特性。这意味着一旦用户使用了这个函数,编译器应该立即停止编译,并抱怨“这个函数被删除了”。

如果看到此错误,应该检查 =delete的函数声明。

要了解 C + + 0x 中引入的这个新特性的更多信息,请查看 这个

在当前的 C + + 0x 标准中,您可以使用 delete 语法显式禁用默认构造函数,例如。

MyClass() = delete;

Gcc 4.6是第一个支持这种语法的版本,所以也许这就是问题所在..。

Gcc 4.6支持删除函数的新特性,您可以在其中编写

hdealt() = delete;

解除缺省构造函数。

在这里,编译器显然已经发现不能生成一个缺省构造函数,并且为你把它 =delete化了。

错误信息显示缺省构造函数已被删除。它甚至说明了原因: 该类包含一个非静态的 const 变量,这个变量不会被默认的 ctor 初始化。

class X {
const int x;
};

因为 X::xconst,所以必须初始化它——但是默认的 ctor 通常不会初始化它(因为它是 POD 类型)。因此,要获得默认的 ctor,您需要自己定义一个(并且它必须初始化 x)。你可以得到同样的情况与一个成员,这是一个参考:

class X {
whatever &x;
};

可能值得注意的是,出于本质上相同的原因,这两种方法也将禁用隐式创建赋值操作符。隐式赋值运算符通常执行成员方式的赋值,但对于 const 成员或引用成员,它不能这样做,因为无法赋值该成员。要使赋值工作,您需要编写自己的赋值运算符。

这就是为什么 const成员应该 一般来说是静态的——当您进行赋值时,无论如何都不能分配 const 成员。在一个典型的例子中,所有的实例都将具有相同的值,因此它们可以共享对单个变量的访问,而不是拥有具有相同值的变量的大量副本。

当然,创建具有不同值的实例是可能的——例如,在创建对象时传递一个值,这样两个不同的对象可以具有两个不同的值。但是,如果尝试执行交换它们之类的操作,const 成员将保留其原始值,而不会被交换。

从 gcc 4.6切换到 gcc 4.8为我解决了这个问题。

当我从一个抽象类继承并且没有实现我的子类中的所有纯虚方法时,我遇到了这个错误。