【问题标题】:error: use of deleted function错误:使用已删除的功能
【发布时间】:2011-08-23 10:16:08
【问题描述】:

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

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

【问题讨论】:

  • 和你正在编译的代码?
  • 我只是想知道错误是什么意思?我还需要发布代码吗?
  • gcc.gnu.org/bugzilla/show_bug.cgi?id=47417 可能有帮助,你也在使用 boost 吗?
  • @Sasquiha ,是的,我正在使用 boost MSM。
  • 因为这是针对此类错误的第一个 Google 匹配项 - 这里不是这种情况,但此类错误的最常见原因是在您向类添加了一些自定义构造函数之后 - 如结果编译器停止创建默认构造函数,如果通过默认构造函数创建了类的实例,则会出现此错误。只需显式添加默认构造函数即可。

标签: c++ gcc g++ c++11 deleted-functions


【解决方案1】:

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

class X {
    const int x;
};

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

class X { 
    whatever &x;
};

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

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

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

【讨论】:

  • @Jeffry Coffin:实际错误消息是作为编辑发布的,最初发布的错误消息仅为C++ error: use of deleted function
  • @Als:对不起,我可能应该明确表示我并没有打算将其作为侮辱或任何关于该命令的内容,只是当前可用的内容表明这些答案显然不是对。
  • 我想你可以在这里帮助我解决我的问题:stackoverflow.com/questions/23349524/…
  • “这就是为什么 const 成员应该通常是静态的” - 有趣,我以前没有遇到过这种情况。所以,习惯上,如果我的类有一些在其生命周期内永远不会改变的属性,而不是const 在构造上它应该只是private,没有非constpublic 接触它的接口?跨度>
  • @OllieFord:这取决于。如果(例如)您将在该字段中具有一个值的对象分配给在该字段中具有不同值的另一个对象,会发生什么?如果它应该被覆盖,那么它不能是 const。如果根本不允许这样做,那么该值可能确实是类型的一部分(例如,模板参数,如果在编译时已知)。
【解决方案2】:

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

int doSomething( int ) = delete;

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

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

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

【讨论】:

  • 出于好奇,什么时候做这样的事情会有帮助?
  • @Peter: 防止隐式转换。
  • 其实它说的是“隐式删除,因为...”,上面的例子是显式的。
  • @Peter R:看起来这是一个例子:en.wikipedia.org/wiki/…
  • @Downvoter:实际的错误消息是作为编辑发布的,最初发布的错误消息只是C++ error: use of deleted function
【解决方案3】:

gcc 4.6 支持删除函数的新特性,你可以在里面写

hdealt() = delete;

禁用默认构造函数。

这里编译器明显看出不能生成默认构造函数,=delete给你了。

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • 类似地,我通过从 2 级基类派生 public virtual 得到相同的结果,其中 1 级基类具有显式删除的默认构造函数。删除 virtual 解决了这个问题,而无需实现所有方法。
    【解决方案5】:

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

    MyClass() = delete;
    

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

    【讨论】:

    • Gcc 4.6 is the first version to support this syntax 我想这可以解释为什么我以前从未见过它,因为我最近才开始使用 gcc4.6。
    • 多年来我一直在 GCC 4.5 中使用这种语法。我的意思是几天。
    • 啊,我一定一直在考虑 GCC 4.6 中的委托 ctor。
    【解决方案6】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多