最終更新日時(UTC): 2025年07月07日 09時03分31秒
Akira Takahashi が更新

履歴 編集

<memory_resource>

# memory_resource(C++17)

`<memory_resource>`ヘッダでは、ポリモルフィックなアロケータ（多相アロケータ、型に依存しないアロケータ）とそれを実装するためのインターフェース、及びその標準実装を提供する。

## インターフェースと多相アロケータ

名前 | 説明 | 対応バージョン
--- | --- | ---
`memory_resource` | アロケータ実装を抽象化するためのインターフェース | C++17
`polymorphic_allocator` | 型によらないアロケータ実装を利用可能なアロケータ | C++17

## 標準`memory_resource`実装

名前 | 説明 | 対応バージョン
--- | --- | ---
`synchronized_pool_resource` | スレッドセーフなメモリプール | C++17
`unsynchronized_pool_resource` | スレッドセーフではないメモリプール | C++17
`monotonic_buffer_resource` | 最後にまとめて領域を解放する`memory_resource` | C++17
`pool_options` | `pool_resource`クラスの内部プール調整のためのクラス | C++17

## 関数

名前 | 説明 | 対応バージョン
--- | --- | ---
`new_delete_resource` | `operator new`、`operator delete`を利用する`memory_resource`を取得 | C++17
`null_memory_resource` | 確保も解放も行わない`memory_resource`を取得 | C++17
`set_default_resource` | デフォルトで使用される`memory_resource`の設定 | C++17
`get_default_resource` | デフォルトで使用される`memory_resource`の取得 | C++17

## 導入された経緯

このクラス導入以前のアロケータはPolicyベースデザインというパターンに基づく設計であったため、アロケータの型がそれを利用する型にも表れてしまっていた。
それによって、利用するアロケータが異なる型は異なるクラスとして扱われてしまいいくつか不便なところがあった。

例えば自作のアロケータ`original_allocator`を作り、利用しようとすると以下のような問題が生じる。

    std::string str1 = "string";
    std::basic_string<char, std::char_traits<char>, original_allocator<char>> str2 = "string";

    //型が違うので比較不可
    auto r = str1 == str2;

    std::vector<int> v1 = {1, 2, 3, 4};

    //型が違うのでコピーできない
    std::vector<int, original_allocator<int>> v2 = v1;

    //比較も不可
    auto r = v1 == v2;

これらの問題の解決の必要性は認識されていたが、従来のアロケータの改修は互換性の問題等から難しいために新しく多相アロケータ（`polymorphic_allocator`）が導入された。
多相アロケータはアロケータの実装を型に出さずに動的に切り替えることのできるアロケータであり、上記の問題を解決することができる。ただし、従来のアロケータを利用するクラスとの間では相変わらず上記の問題が残り続ける。

本ヘッダにはその多相アロケータに関連するクラスや関数群が定義されている。

またこれらの追加に伴い、標準ライブラリ内でアロケータを用いるクラスにデフォルトで`polymorphic_allocator`を利用するエイリアスが導入された。これは各クラスのヘッダ毎に宣言される。

## `polymorphic_allocator`を用いるエイリアスが提供されるクラス

以下は全て`std::pmr`名前空間配下に宣言されている。

- `basic_string`
  - `string`
  - `wstring`
  - `u16string`
  - `u32string`
- `deque`
- `forward_list`
- `list`
- `vector`
- `map`
- `multimap`
- `set`
- `multiset`
- `unordered_map`
- `unordered_multimap`
- `unordered_set`
- `unordered_multiset`
- `match_results`
  - `cmatch`
  - `wcmatch`
  - `smatch`
  - `wsmatch`

## バージョン

### 言語

- C++17

### 処理系

- Clang: ??
- GCC: 9.1 ✅
- Visual C++: 2017 update 6 ✅

## 関連項目

`<scoped_allocator>`

## 参照

- C++1z 多相アロケータとメモリプール - Faith and Brave - C++で遊ぼう
- memory_resourceについて - 本の虫
- Polymorphic Allocator in C++17 - Qita
- C++17の新機能 アロケータ編 / new features of C++17 - allocator
- Allocators@C++11 - Cryolite
- P0220R1 Adopt Library Fundamentals V1 TS Components for C++17 (R1)
- P0337r0 | Delete operator= for polymorphic_allocator
- Working Draft, C++ Extensions for Library Fundamentals, Version 2
- N1850 Towards a Better Allocator Model
- N3525 Polymorphic Allocators
- N3726 Polymorphic Memory Resources
- N3816 Polymorphic Memory Resources - r1
- N3916 Polymorphic Memory Resources - r2