web-dev-qa-db-ja.com

なぜstd :: allocatorの構造と破棄関数はc ++ 17で非推奨になりましたか?

C++ 17仕様では、std::allocatorオブジェクトのconstructおよびdestroyメンバーを廃止します。ワーキンググループは、「std :: allocatorの冗長メンバーを非推奨にする」という見出しの下で、他のメンバー関数を非推奨にする理由を説明しました here

ただし、これら2つのメンバーが非推奨になった理由や、その機能を置き換えるための推奨事項については特に言及していません。その意味は、代わりにstd::allocator_traits::constructを使用することだと想定しています。

std::allocator_traits::constructについてのこのコメント が原因で、constructの実装が実際に必要な場合があるかどうかについて少し混乱しています。

この関数は配置newへの自動フォールバックを提供するため、メンバー関数construct()は、C++ 11以降のオプションのAllocator要件です。

カスタムアロケーター(たとえば、memalignを使用するページアラインメモリ)の場合、配置newにフォールバックすると、常に正しい動作が生成されますか?

42

アロケータ要件テーブル は、construct(c, args)が提供される場合、「Cc型のオブジェクトを構築する必要がある」ことを示します。

それは、1)Cのコンストラクターに渡される引数、または2)これらの引数が渡される方法について絶対に何も述べていません。それがアロケーターの選択です。実際、標準の2つのアロケーターは、Cのコンストラクターに渡す前に引数を混乱させます。 _std::scoped_allocator_adaptor_ および _std::pmr::polymorphic_allocator_ 。特に、_std::pair_を構築する場合、pairのコンストラクターに渡す引数は、受け取ったものとは似ていない場合もあります。

完全に転送する必要もありません。 C++ 03スタイルのconstruct(T*, const T&)は、非効率的であれば準拠しています。

_std::allocator_のconstructdestroyは役に立たないので非推奨です:良いC++ 11以降のコードはそれらを直接呼び出すべきではなく、デフォルト以上は何も追加しません。


メモリアライメントの処理は、allocateではなく、constructのタスクである必要があります。

22
T.C.

この機能は、他の機能とともに論文から削除されました D0174R0 Deprecating Vestigial Library Parts in C++ 17 。関連するセクションを見ると、

Std :: allocatorの多くのメンバーは、std::allocator_traits<allocator<T>>によって生成される動作を重複して複製し、このクラスを単純化するために安全に削除できます。さらに、フリー関数としてのaddressofは、正しいタイプのアロケーターオブジェクトを必要とするstd::allocator<T>::addressに優先します。最後に、参照型エイリアスは他のアロケーターで拡張するための予想される手段として最初に提供されましたが、アロケーター要件を指定したときに有用な目的を果たさないことが判明しました(17.6.3.5 [allocator.requirements])。

このアロケータタイプを明示的に使用したコードとの後方互換性を損なうことなくこれらのメンバーを削除することはできませんが、それらの継続使用を推奨するべきではありません。型が汎用アロケーターをサポートする場合、アロケーターのメンバーに直接アクセスするのではなく、allocator_traitsを介してアロケーターの機能にアクセスする必要があります-そうでない場合、デフォルトに合成する特性に依存するアロケーターを適切にサポートしません行動。同様に、ユーザーが汎用アロケーターをサポートするつもりがない場合は、直接new、deleteを呼び出し、ポインター型などのstd :: allocatorの他のプロパティを直接引き受けるほうがはるかに簡単です。

重点鉱山

そのため、アロケーターの特性があるため、アロケーターのすべてのコードを複製する必要はありませんでした。 std::allocator_traits を見ると、

allocate
deallocate
construct
destroy
max_size

アロケータ内の関数の代わりに使用できる静的関数。

9
NathanOliver