错误:使用已删除的功能


121

我一直在研究一个朋友写的一些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
以及您正在编译的代码?
ColWhi

我只是想知道错误是什么意思?我是否还需要为此发布代码?
穿梭车2011年

1
gcc.gnu.org/bugzilla/show_bug.cgi?id=47417可能有帮助,您是否也在使用boost?
2011年

@Sasquiha,是的,我正在使用增强MSM。
穿梭车2011年

20
由于这是此类错误的第一个Google匹配项-此处不是这种情况,但是导致此类错误的最常见原因是在您向类中添加了一些自定义构造函数之后-导致编译器停止创建默认构造函数,如果曾经通过默认构造函数创建该类的实例,则会出现此错误。只需显式添加默认构造函数。
SF。

Answers:


170

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

class X {
    const int x;
};

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

class X { 
    whatever &x;
};

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

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

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


@Jeffry Coffin:实际的错误消息是作为编辑发布的,而最初的错误消息只是发布的C++ error: use of deleted function
Alok Save

1
@Als:对不起,我可能应该明确指出,我不打算以此作为侮辱或任何命令,只是因为目前可获得的信息使这些答案显然不正确。
杰里·科芬

没问题,我并不是要坚定不移...您的回答很棒,可以最好地说明情况。从我+1 :)
Alok保存

我想你也许能帮助我与我的问题就在这里,请:stackoverflow.com/questions/23349524/...
Saher Ahwal

2
@OllieFord:这取决于。如果(例如)将在该字段中具有一个值的对象分配给在该字段中具有不同值的另一个对象,该怎么办?如果应将其覆盖,则不能为const。如果根本不允许这样做,则该值实际上可能是该类型的一部分(例如,模板参数,如果在编译时知道的话)。
杰里·科芬,2015年

11

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

int doSomething( int ) = delete;

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

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

要了解有关C ++ 0x中引入的此新功能的更多信息,请查看此内容


7
出于好奇,什么时候做这样的事情会有所帮助?
佩佩

@Peter:防止隐式转换。
R. Martinho Fernandes

7
实际上,它说“因为...而被隐式删除”,上面的示例是明确的。
乔治·弗里兹

@Peter R:看起来这是一个例子:en.wikipedia.org/wiki/...
shuttle87

1
@Downvoter:实际的错误消息是作为编辑发布的,而最初的错误消息只是发布的C++ error: use of deleted function
Alok Save

4

gcc 4.6支持删除功能的新功能,您可以在其中编写

hdealt() = delete;

禁用默认构造函数。

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


2

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


1
同样,我是public virtual从第二级基类派生而来的,其中第二级基类具有显式删除的默认构造函数。删除virtual解决了该问题,而无需实施所有方法。
Maitre Bart

1

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

MyClass() = delete;

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


Gcc 4.6 is the first version to support this syntax我想这可以解释为什么最近我刚刚开始使用gcc4.6之前从未见过它。
穿梭车2011年

2
多年来,我一直在GCC 4.5中使用这种语法。我是说几天
R. Martinho Fernandes

啊,我一定在想GCC 4.6中的委托ctor。
jarmond

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.