C++ 11でどのようにユニオンが拡張されたかを理解しようとしています。変更された点の1つは、非静的なデータメンバーを特別なメンバー関数で使用することです。労働組合が非自明な特殊なメンバ関数(デフォルトコンストラクタ、コピー/移動コンストラクタ、コピー/移動の割り当て、またはデストラクタ)と非静的データメンバが含まれている場合cppreference.comC++ 11のユニオン:デフォルトのコンストラクタが削除されているようです。
からは、その機能がデフォルトで削除されます組合では、プログラマが明示的に定義する必要があります。 多くても1つのデータメンバーにデフォルトメンバー初期化子を設定できます。
私は次のコードをしようとしている:ここ
struct X
{
~X() {};
};
union U
{
X x;
~U() {};
};
int main()
{
U s1{}; // works, probably aggregate initialization
U s2; // DOES NOT compile, why?
}
をX
は(組合のデータメンバーとして使用される)ユーザ提供デストラクタの故にデストラクタを有します共用体はデフォルトで削除されます。したがって私は明示的に1つを提供します。しかし、コードがコンパイルに失敗し、エラー
ノートで:デフォルトの定義が病気に形成されたことになるので「U :: Uは()」暗黙的に削除されます。
コードがあればコンパイル私は最後の行U s2;
を削除します。
質問ここでは何が起こっていますか?なぜU s1{};
がコンパイルされますが、U s2;
はありません。ユニオンのデフォルトのctorは削除済みとしてマークされていますか(なぜそうなのですか?)、最初のケースでは初期化を集計していますか? U(){}; // not U() = default;
を提供した場合、コードはコンパイルされます(しかし、私はX
のctorしか提供しません)。
組合:
EDIT
標準(N4527)に掘り後、9.5/2 [class.union]
[注意:任意の非静的な場合(12.8)、コピーコンストラクタ(12.8)、コピーコンストラクタ(12.8)、コピー代入演算子(12.8)、移動代入演算子(12.8)、またはデストラクタ(12.4)があり、対応するメンバー関数ユニオンの使用はユーザー提供するか、ユニオン用に暗黙的に削除する必要があります(8.4.3)。 -endnote]
これはgccバグ(現在はhereと報告されているようです)です。コードはclangとgcc 4.8.2以前でコンパイルされ、gcc4.9以降で動作します(指摘のために@ T.Cに感謝します)。
コンパイラ:g ++ 5.3、-std=c++11
が使用されます。
[Clang](http://coliru.stacked-crooked.com/a/b58a360400009fa9)はこのコードに完全に満足しています。これは実際にはGCCのバグのように見えます。 –
@ T.C。はい、私は実際にあなたのコメントの後にこれを見ました。私は最初印象clangを持っていたそれを拒否していた、いくつかの変更されたバージョンをテストされている可能性があります。質問の最後の行を編集しました。ありがとうございます。 – vsoftco
@ T.C。私は標準を掘り下げようとします... – vsoftco