C++1zから、アロケートする型を規定しないアロケータと、それを利用したメモリプールの仕組みが導入されます。
std::allocator<T>クラスは型Tのオブジェクトをアロケートする機能を提供しますが、アロケートする型ごとにアロケータオブジェクトが必要になり、メモリリソースを共有することが難しい仕組みになっています。
C++1zの多相アロケータは、あらゆる型のオブジェクトをアロケートする基本的な仕組みとなります。
この目的のために<memory_resource>ヘッダが新設され、大きく以下の2つのクラスが定義されます:
std::pmr::polymorphic_allocatorstd::pmr::memory_resource
polymorphic_allocatorクラスは共有メモリリソースを使用するメモリアロケータ。memory_resourceクラスは共有メモリリソースの基本クラスになります。
memory_resourceから派生したクラスを共有メモリリソースとして使用できます。標準では<memory_resource>ヘッダに、以下の3つのメモリリソースが定義されます。
std::pmr::synchronized_pool_resource: スレッドセーフなメモリプールstd::pmr::unsynchronized_pool_resource: スレッドセーフではないメモリプールstd::pmr::monotonic_buffer_resource: 一度に全てを解放するような状況で使用する、高速なメモリアロケートを行う特殊なメモリリソース
また、多相アロケータとメモリリソースを扱いやすくするために、フリーストアを使用する標準の全てのコンテナに対して、polymorphic_allocatorを指定済みの別名がstd::pmr名前空間に定義されます。これを使用してコードを書くと、以下のようになります。
#include <memory_resource> #include <vector> #include <string> int main() { // スレッドセーフなメモリプールを使用する std::pmr::synchronized_pool_resource mem_res; // vとsでメモリリソースを共有する std::pmr::vector<int> v(&mem_res); std::pmr::string s(&mem_res); }
polymorphic_allocatorクラスはmemory_resourceオブジェクトへのポインタをコンストラクタで受け取るので、コンテナにメモリリソースへのポインタを渡せば、polymorphic_allocatorにメモリリソースが伝搬されます。メモリリソースをコンテナに渡さない場合は、グローバルなデフォルトのメモリリソースが使用されます。デフォルトのメモリリソースは、std::pmr::set_default_resource()関数で設定できます。
#include <memory_resource> #include <vector> #include <string> int main() { // スレッドセーフなメモリプールを // デフォルトのメモリリソースとして使用する std::pmr::synchronized_pool_resource mem_res; std::pmr::set_default_resource(&mem_res); // vとsでメモリリソースを共有する。 // デフォルトのメモリリソースを使用する std::pmr::vector<int> v; std::pmr::string s; }
最初のデフォルトメモリリソースとして何が使われるかは未規定です。
参照
- N3525 Polymorphic Allocators
- N3726 Polymorphic Memory Resources
- N3816 Polymorphic Memory Resources - r1
- N3916 Polymorphic Memory Resources - r2
- P0220R0 Adopt Library Fundamentals TS for C++17
- P0220R1 Adopt Library Fundamentals V1 TS Components for C++17 (R1)
- P0337R0 Delete
operator=forpolymorphic_allocator
お断り
この記事の内容は、C++1zが正式リリースされる際には変更される可能性があります。正式リリース後には、C++日本語リファレンスサイトcpprefjpの以下の階層の下に解説ページを用意する予定です。