エラー:削除された関数の使用


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、

エラーが何を意味するのかもっと疑問に思っていましたか?そのためのコードも投稿する必要がありますか?
シャトル87

1
gcc.gnu.org/bugzilla/show_bug.cgi?id=47417が役立つ場合があります。また、ブーストを使用していますか?
ColWhi、

@Sasquiha、はい、ブーストMSMを使用しています。
シャトル87

20
これは、このタイプのエラーに対する最初のGoogleの一致として現れる-ここではそうではないが、この種のエラーの最も一般的な原因は、クラスにカスタムコンストラクターを追加した後-結果として、コンパイラーがデフォルトコンストラクターの作成を中止する、そしてクラスのインスタンスがデフォルトのコンストラクタを介して作成された場合、このエラーが表示されます。デフォルトのコンストラクタを明示的に追加するだけです。
SF。

回答:


170

エラーメッセージは、デフォルトのコンストラクタが暗黙的に削除されたことを明確に示しています。それは理由も示しています:クラスには非静的なconst変数が含まれており、デフォルトのctorによって初期化されません。

class X {
    const int x;
};

以来X::xされconst、それが初期化されなければならない-しかし、(それはPODタイプだから)デフォルトのctorのは、通常はそれを初期化しません。したがって、デフォルトのctorを取得するには、自分で定義する必要があります(そして初期化する必要がありますx)。参照であるメンバーで同じ種類の状況を取得できます。

class X { 
    whatever &x;
};

基本的に同じ理由で、これらの両方が代入演算子の暗黙的な作成も無効にすることはおそらく注目に値します。暗黙の代入演算子は通常、メンバーごとの代入を行いますが、constメンバーまたは参照メンバーでは、メンバーを割り当てることができないため、それを行うことはできません。割り当てを機能させるには、独自の割り当て演算子を作成する必要があります。

これが、constメンバーが通常静的である必要がある理由です。割り当てを行うとき、とにかくconstメンバーを割り当てることはできません。典型的なケースでは、すべてのインスタンスが同じ値を持つため、すべて同じ値を持つ変数のコピーを多数持つのではなく、単一の変数へのアクセスを共有することもできます。

もちろん、異なる値でインスタンスを作成することも可能です-(たとえば)オブジェクトを作成するときに値を渡すため、2つの異なるオブジェクトが2つの異なる値を持つことができます。ただし、それらを交換するなどの操作を行おうとすると、constメンバーは交換される代わりに元の値を保持します。


@Jeffry Coffin:実際のエラーメッセージは編集として投稿され、最初のエラーメッセージのみが投稿されましたC++ error: use of deleted function
Alok Save

1
@アルス:申し訳ありませんが、侮辱やその注文に関することを意図していないことを明示しているはずですが、現在入手可能なものから、それらの回答が正しくないことが明らかになりました。
ジェリーコフィン

問題ありません、私は頑固であるつもりはありませんでした...あなたの答えは素晴らしく、状況を最もよく説明しています。私からの+1 :)
Alok Save

私はあなたがここに私の問題で私を助けることができるかもしれないと仮定してください。stackoverflow.com/questions/23349524/...
Saher Ahwal

2
@OllieFord:状況によります。(たとえば)そのフィールドにある値を持つオブジェクトを、そのフィールドに異なる値を持つ別のオブジェクトに割り当てるとどうなりますか?上書きする必要がある場合は、constにすることはできません。それがまったく許可されない場合は、値が実際に型の一部である可能性があります(たとえば、コンパイル時にわかっている場合は、テンプレートパラメータ)。
Jerry Coffin

11

とマークされている関数を使用していますdeleted
例えば:

int doSomething( int ) = delete;

= deleteはC ++ 0xの新機能です。これは、ユーザーがそのような関数を使用すると、コンパイラーはすぐにコンパイルを停止し、「この関数は削除された」と警告する必要があることを意味します。

このエラーが表示された場合は、関数宣言を確認してください=delete

より多くのC ++ 0xの中に導入されたこの新機能について知るためには、チェックこれを行います。


7
好奇心から、そのようなことをすることが役立つのはいつですか?
Pepe

@Peter:暗黙的な変換を防止します。
R.マルティーニョフェルナンデス、

7
実際には、「...のために暗黙的に削除されました」と表示され、上記の例は明示的です。
Georg Fritzsche、

:@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 virtual2番目のレベルの基本クラスから派生させることで、1番目のレベルの基本クラスに明示的に削除されたデフォルトコンストラクターがあることで、同じ結果を得ました。削除すると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を使い始めたばかりなので、これまでに見たことがない理由を説明していると思います。
シャトル87

2
この構文をGCC 4.5で何年も使用しています。私は日を意味します。
R.マルティーニョフェルナンデス

ああ、私はGCC 4.6にある委任されたアクターを考えていたに違いありません。
ジャーモンド

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.