26

std::unique_ptr最近、STLコンテナの要素が受け入れられるという事実に驚いています。これは、これらの要素が以下の機能を提供するために必要であると考えたためです(このページでも同じです)。

  • 引数のないパブリックデフォルトコンストラクタ
  • パブリックコピーコンストラクタ
  • パブリックコピー代入演算子関数
  • パブリックデストラクタ

ただしstd::unique_ptr、保持しているポインタを単一のオブジェクトが所有するようにコピーすることはできません。これは、上記の要件と矛盾します。

規格は要件を変更しましたか?もしそうなら、変更は何ですか?おそらく、移動可能なオブジェクトまたはコピー可能なオブジェクトのいずれかで十分ですか?C ++ 11以降、要件が変更されているかどうかをWebで検索しましたが、役立つページが見つかりません...

4

1 に答える 1

24

はい、標準ライブラリコンテナの要件に大きな変更がありました。包括的なリストを提供するのは難しいですが(たくさんありました)、ここにいくつかの重要なものがあります:

std::vector通常、そのメンバーがMoveConstructibleおよびMoveAssignableである必要があるだけです。std :: vectorには、より厳しい要件を課す多くのメンバー関数があります。vector::push_backMoveまたは CopyConstructible(右辺値と左辺値のどちらを渡すかによって異なります)が必要ですが、newvector::emplace_backでは、(ベースライン要件に加えて)指定されたパラメーターを受け取るアクセス可能なコンストラクターが存在する必要があります。明らかに、vectorのコピーコンストラクタ/代入を呼び出すには、型がCopyConstructibleである必要があります(つまり、をコピーすることはできませんstd::vector<unique_ptr>)。

同様に、他のほとんどのコンテナでは、タイプの制限が緩和されています。またemplace、メンバーをインプレースで構築できるメンバー関数や、l/rvalue挿入関数もあります。つまり、値をコピーする必要はありません。それらを移動したり、インプレースで構築したりできます。

コンストラクタまたはデストラクタはいずれもパブリックである必要はありません。すべての構築は、呼び出しからallocator_traits<Allocator>::construct呼び出しを介して行われます。したがって、アロケータを提供する場合は、コンストラクタ/デストラクタをプライベートにすることができます。もちろん、アロケータクラスがそれらにアクセスできる限り。

つまり、要件はそれほど厳密ではありませんが、もう少し複雑です。コンテナで特定の操作を実行することを制限すると、多くのことを回避できます。

于 2012-11-27T06:13:15.893 に答える