我一直在研究朋友编写的一些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()
。
一般来说,这个错误是什么意思?发生此类错误时,我应该寻找什么?
答案 0 :(得分:141)
错误消息清楚地表明默认构造函数已被隐式删除 。它甚至说明了原因:该类包含一个非静态的const变量,它不会被默认的ctor初始化。
class X {
const int x;
};
由于X::x
为const
,因此必须对其进行初始化 - 但默认的ctor通常不会初始化它(因为它是POD类型)。因此,要获取默认ctor,您需要自己定义一个(并且必须初始化x
)。您可以使用作为参考的成员获得相同的情况:
class X {
whatever &x;
};
值得注意的是,由于基本相同的原因,这两者也将禁用隐式创建赋值运算符。隐式赋值运算符通常执行成员分配,但是使用const成员或引用成员时,它无法执行此操作,因为无法分配成员。要使分配工作,您需要编写自己的赋值运算符。
这就是const
成员通常是静态的原因 - 当你执行赋值时,无论如何都不能指定const成员。在典型情况下,所有实例都将具有相同的值,因此它们可以共享对单个变量的访问权,而不是拥有大量具有相同值的变量副本。
当然,可以创建具有不同值的实例 - 您(例如)在创建对象时传递值,因此两个不同的对象可以具有两个不同的值。但是,如果您尝试执行类似交换的操作,const成员将保留其原始值而不是交换。
答案 1 :(得分:5)
您正在使用一个标记为deleted
的功能
例如:
int doSomething( int ) = delete;
= delete是C ++ 0x的新功能。这意味着一旦用户使用这样的功能,编译器应立即停止编译并抱怨“此功能被删除”。
如果您看到此错误,则应检查=delete
的函数声明。
要了解有关C ++ 0x中引入的这一新功能的更多信息,请检查this out。
答案 2 :(得分:2)
gcc 4.6支持已删除功能的新功能,您可以在其中编写
hdealt() = delete;
禁用默认构造函数。
这里编译器显然已经看到无法生成默认构造函数,=delete
为你做了。
答案 3 :(得分:1)
在当前的C ++ 0x标准中,您可以使用删除语法显式禁用默认构造函数,例如
MyClass() = delete;
Gcc 4.6是第一个支持这种语法的版本,所以也许这就是问题......
答案 4 :(得分:1)
class C
{
public:
const int x ;
} ;
int main()
{
C c ;
}
如果此处的人员是正确的,则应该提供类似的错误消息。
答案 5 :(得分:1)
从gcc 4.6切换到gcc 4.8为我解决了这个问题。
答案 6 :(得分:0)
当我从抽象类继承而未在子类中实现所有纯虚拟方法时,遇到了此错误。