153

我一直在编写一个朋友编写的一些 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’

编辑:这来自使用 boost MSM 的部分代码:Boost Webpage

Edit2:源代码中的任何地方都没有= delete()使用。

一般来说,这个错误是什么意思?发生此类错误时我应该寻找什么?

4

6 回答 6

197

错误消息清楚地表明默认构造函数已被隐式删除。它甚至说明了原因:该类包含一个非静态的 const 变量,默认 ctor 不会初始化该变量。

class X {
    const int x;
};

由于X::xis const,它必须被初始化——但默认的 ctor 通常不会初始化它(因为它是 POD 类型)。因此,要获得默认 ctor,您需要自己定义一个(并且它必须初始化x)。您可以使用作为参考的成员获得相同的情况:

class X { 
    whatever &x;
};

可能值得注意的是,出于基本相同的原因,这两者也将禁用赋值运算符的隐式创建。隐式赋值运算符通常按成员进行赋值,但对于 const 成员或引用成员,它不能这样做,因为无法分配成员。要使赋值起作用,您需要编写自己的赋值运算符。

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

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

于 2011-05-11T15:35:31.880 回答
12

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

int doSomething( int ) = delete;

=delete 是 C++0x 的一个新特性。这意味着一旦用户使用该功能,编译器应立即停止编译并抱怨“此功能已删除”。

如果您看到此错误,您应该检查=delete.

要了解有关 C++0x 中引入的这一新特性的更多信息,请查看内容。

于 2011-05-11T15:28:50.280 回答
4

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

hdealt() = delete;

禁用默认构造函数。

这里编译器显然已经看到无法生成默认构造函数,并=delete为您生成了它。

于 2011-05-11T15:32:42.217 回答
4

从抽象类继承并且未在我的子类中实现所有纯虚拟方法时遇到此错误。

于 2019-07-25T23:10:28.927 回答
2

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

MyClass() = delete;

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

于 2011-05-11T15:30:54.420 回答
1

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

于 2013-12-13T21:14:27.220 回答