3

私はc++11のwikiエントリを読んでいて、重要なメンバーリンクの配置を新しいと呼ぶ無制限の結合のセクションを見つけましたが、ここでの例は削除と一致しませんでした。

だから私の質問は:無制限のユニオンのためにプレースメントを削除する必要がありますか?はいの場合、どのように?そうでない場合、なぜですか?デストラクタを呼び出すだけで十分でしょうか?

例:

class U_t
{
  public:
    union U
    {
        string s;
        U () { new (s) string(); }
    }
    U _data;
    ~U_t () { 
       _data.s.~string();
       //and now what?
    }
}
4

1 に答える 1

2

§9.5/2ユニオンの非静的データメンバーに自明でないデフォルトコンストラクター、コピーコンストラクター、ムーブコンストラクター、コピー代入演算子、ムーブ代入演算子、またはデストラクタがある場合、ユニオンの対応するメンバー関数はユーザーである必要があります-提供されるか、ユニオンに対して暗黙的に削除されます。

§9.5/3std:: stringは、すべての特殊メンバー関数の自明でないバージョンを宣言するため、[ユニオン]には、暗黙的に削除されたデフォルトコンストラクター、コピー/ムーブコンストラクター、コピー/ムーブ代入演算子、およびデストラクタがあります。[ユニオン]を使用するには、これらのメンバー関数の一部またはすべてをユーザーが提供する必要があります。

§9.5/4一般に、ユニオンのアクティブなメンバーを変更するには、明示的なデストラクタ呼び出しと配置新しい演算子を使用する必要があります。

そうです、あなたが持っているものと同様に、それはデストラクタ呼び出しを必要とします。

ただし、このようなものを安全に使用するには、アクティブなタイプを常に追跡する必要があるため、はるかに複雑になります。非PODタイプのユニオンを安全に使用することは非常に困難です。私があなたの場合は、PODのみを使用するか、boost::variant

于 2012-09-11T00:02:32.953 に答える