Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lang/cpp26.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ C++26とは、2026年中に改訂される予定の、C++バージョンの通


### スマートポインタ・メモリ関連
- 動的確保したオブジェクトに値の意味論をもたせてディープコピーさせるユーティリティクラスとして、[`<memory>`](/reference/memory.md)に[`std::indirect`](/reference/memory/indirect.md.nolink)クラスと[`std::polymorphic`](/reference/memory/polymorphic.md.nolink)クラスを追加
- 動的確保したオブジェクトに値の意味論をもたせてディープコピーさせるユーティリティクラスとして、[`<memory>`](/reference/memory.md)に[`std::indirect`](/reference/memory/indirect.md)クラスと[`std::polymorphic`](/reference/memory/polymorphic.md)クラスを追加
- [`std::weak_ptr`](/reference/memory/weak_ptr.md)を非順序連想コンテナのキーとして使用できるよう、[`<memory>`](/reference/memory.md)に所有権ベースのハッシュ値を取得する関数オブジェクト[`std::owner_hash`](/reference/memory/owner_hash.md)、および所有権ベースの等値比較を行う関数オブジェクト[`std::owner_equal`](/reference/memory/owner_equal.md)を追加
- 関連して、[`std::shared_ptr`](/reference/memory/shared_ptr.md)クラスと[`std::weak_ptr`](/reference/memory/weak_ptr.md)クラスのメンバ関数として、`owner_hash()`と`owner_equal()`を追加
- [`std::shared_ptr`](/reference/memory/shared_ptr.md)クラスとその関連機能を`constexpr`対応
Expand Down
4 changes: 2 additions & 2 deletions lang/cpp26/feature_test_macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
|`__cpp_lib_function_ref`|`202306L`|[`<functional>`](/reference/functional.md)に[`std::function_ref`](/reference/functional/function_ref.md)を追加|[`<functional>`](/reference/functional.md)|
|`__cpp_lib_hazard_pointer`|`202306L`|ハザードポインタのライブラリ[`<hazard_pointer>`](/reference/hazard_pointer.md.nolink)を追加|[`<hazard_pointer>`](/reference/hazard_pointer.md.nolink)|
|`__cpp_lib_hive`|`202502L`|シーケンスコンテナのライブラリ[`<hive>`](/reference/hive.md.nolink)を追加|[`<hive>`](/reference/hive.md.nolink)|
|`__cpp_lib_indirect`|`202502L`|[`<memory>`](/reference/memory.md)に[`std::indirect`](/reference/memory/indirect.md.nolink)と[`std::polymorphic`](/reference/memory/polymorphic.md.nolink)を追加|[`<memory>`](/reference/memory.md)|
|`__cpp_lib_indirect`|`202502L`|[`<memory>`](/reference/memory.md)に[`std::indirect`](/reference/memory/indirect.md)と[`std::polymorphic`](/reference/memory/polymorphic.md)を追加|[`<memory>`](/reference/memory.md)|
|`__cpp_lib_inplace_vector`|`202603L`|容量固定の可変長配列のライブラリ[`<inplace_vector>`](/reference/inplace_vector.md)を追加|[`<inplace_vector>`](/reference/inplace_vector.md)|
|`__cpp_lib_integer_sequence`|`202511L`|[`std::integer_sequence`](/reference/utility/integer_sequence.md)を[構造化束縛](/lang/cpp17/structured_bindings.md)と[`template for`文](/lang/cpp26/expansion_statements.md)で使用できるよう、タプルインタフェースの特殊化を追加|[`<utility>`](/reference/utility.md)|
|`__cpp_lib_is_sufficiently_aligned`|`202411L`|[`<mdspan>`](/reference/mdspan.md)に、要素アクセスにアライメント保証を与える[`std::aligned_accessor`](/reference/mdspan/aligned_accessor.md)を追加|[`<memory>`](/reference/memory.md)|
Expand All @@ -126,7 +126,7 @@
|`__cpp_lib_parallel_algorithm`|`202506L`|[`<algorithm>`](/reference/algorithm.md)と[`<memory>`](/reference/memory.md)のアルゴリズムを並列実行に対応|[`<algorithm>`](/reference/algorithm.md), [`<numeric>`](/reference/numeric.md), [`<memory>`](/reference/memory.md)|
|`__cpp_lib_parallel_scheduler`|`202506L`|[`<execution>`](/reference/execution.md)に[`std::execution::parallel_scheduler`](/reference/execution/execution/parallel_scheduler.md)を追加|[`<execution>`](/reference/execution.md)|
|`__cpp_lib_philox_engine`|`202406L`|[`<random>`](/reference/random.md)に[`std::philox_engine`](/reference/random/philox_engine.md)、[`std::philox4x32`](/reference/random/philox4x32.md)、[`std::philox4x64`](/reference/random/philox4x64.md)を追加|[`<random>`](/reference/random.md)|
|`__cpp_lib_polymorphic`|`202502L`|[`<memory>`](/reference/memory.md)に[`std::indirect`](/reference/memory/indirect.md.nolink)と[`std::polymorphic`](/reference/memory/polymorphic.md.nolink)を追加|[`<memory>`](/reference/memory.md)|
|`__cpp_lib_polymorphic`|`202502L`|[`<memory>`](/reference/memory.md)に[`std::indirect`](/reference/memory/indirect.md)と[`std::polymorphic`](/reference/memory/polymorphic.md)を追加|[`<memory>`](/reference/memory.md)|
|`__cpp_lib_print`|`202406L`|[`std::print()`](/reference/print/print.md)と[`std::println()`](/reference/print/println.md)にロックを取得せず高速に書き出す最適化を許可<br/>[`std::enable_nonlocking_formatter_optimization`](/reference/format/enable_nonlocking_formatter_optimization.md)を追加|[`<print>`](/reference/print.md), [`<ostream>`](/reference/ostream.md)|
|`__cpp_lib_ranges`|`202406L`|[`std::indirectly_unary_invocable`](/reference/iterator/indirectly_unary_invocable.md)などのコンセプトの共通参照要件を削除|[`<algorithm>`](/reference/algorithm.md), [`<functional>`](/reference/functional.md), [`<iterator>`](/reference/iterator.md), [`<memory>`](/reference/memory.md), [`<ranges>`](/reference/ranges.md)|
|`__cpp_lib_ranges_as_const`|`202311L`|[`std::basic_const_iterator`](/reference/iterator/basic_const_iterator.md)を元の要素へのキャストを可能にする|[`<ranges>`](/reference/ranges.md)|
Expand Down
8 changes: 8 additions & 0 deletions reference/memory.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@
| [`inout_ptr`](memory/inout_ptr.md) | スマートポインタへの入出力サポートヘルパ関数(function template) | C++23 |


## 値の意味論をもつ間接ストレージ

| 名前 | 説明 | 対応バージョン |
|------|------|----------------|
| [`indirect`](memory/indirect.md) | 動的確保したオブジェクトに値の意味論をもたせるクラス(class template) | C++26 |
| [`polymorphic`](memory/polymorphic.md) | 動的確保したオブジェクトに値の意味論をもたせ、派生型を多態的に保持するクラス(class template) | C++26 |


## スマートポインタのアトミック操作

| 名前 | 説明 | 対応バージョン |
Expand Down
165 changes: 165 additions & 0 deletions reference/memory/indirect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# indirect
* memory[meta header]
* std[meta namespace]
* class template[meta id-type]
* cpp26[meta cpp]

```cpp
namespace std {
template <class T, class Allocator = allocator<T>>
class indirect;

namespace pmr {
template <class T>
using indirect = std::indirect<T, polymorphic_allocator<T>>;
}
}
```
* allocator[link allocator.md]
* polymorphic_allocator[link /reference/memory_resource/polymorphic_allocator.md]

## 概要
`std::indirect`クラスは、動的確保したオブジェクトに値の意味論をもたせる型である。

ポインタやスマートポインタは参照の意味論をもつため、クラスのメンバとして使うとコピーや`const`の伝播が正しく行われず、クラスの特殊メンバ関数を正しく生成できないことがある。

`std::indirect`クラスは所有するオブジェクトを動的確保しつつ、以下のように値型として振る舞う:

- ディープコピー: `std::indirect`オブジェクトをコピーすると、所有するオブジェクト`T`がそのコピーコンストラクタによって複製される
- `const`の伝播: `const`なアクセス経路から所有オブジェクトにアクセスすると、所有オブジェクトにも`const`が伝播する(`operator*`/`operator->`に`const`版と非`const`版がある)
- 不完全型のサポート: テンプレートパラメータ`T`は不完全型でもよい。これにより、再帰的なデータ構造を表現できる

これらの性質によって、`std::indirect`クラスのオブジェクトはクラスのメンバとして保持するのに適しており、コンパイラによる特殊メンバ関数の自動生成と協調して動作する。

所有オブジェクトを持たない状態を「無効値状態 (valueless state)」と呼ぶ。`std::indirect`オブジェクトが無効値状態になるのは、ムーブ後に空となった場合のみである。無効値状態のオブジェクトに対する`operator*`や`operator->`の呼び出しは未定義動作を引き起こす。無効値状態かどうかは[`valueless_after_move()`](indirect/valueless_after_move.md)メンバ関数で判定できる。

派生型のオブジェクトを多態的に保持したい場合は、[`std::polymorphic`](polymorphic.md)クラスを使用する。


## テンプレートパラメータ制約
- `Allocator`はCpp17Allocator要件を満たすこと
- [`std::allocator_traits`](/reference/memory/allocator_traits.md)`<Allocator>::value_type`が`T`と同じ型であること


## 適格要件
- 以下のいずれかの場合に、プログラムは不適格となる
- `T`がオブジェクト型でない
- 配列型である
- (CV修飾された) [`std::in_place_t`](/reference/utility/in_place_t.md)である
- (CV修飾された) [`std::in_place_type_t`](/reference/utility/in_place_type_t.md)の特殊化である
- `std::indirect`の明示的特殊化・部分特殊化をユーザーが宣言した場合、動作は未定義である


## メンバ関数
### 構築・破棄

| 名前 | 説明 | 対応バージョン |
|------|------|----------------|
| [`(constructor)`](indirect/op_constructor.md) | コンストラクタ | C++26 |
| [`(destructor)`](indirect/op_destructor.md) | デストラクタ | C++26 |
| [`operator=`](indirect/op_assign.md) | 代入演算子 | C++26 |

### 値へのアクセス

| 名前 | 説明 | 対応バージョン |
|------|------|----------------|
| [`operator*`](indirect/op_deref.md) | 所有するオブジェクトへの参照を取得する | C++26 |
| [`operator->`](indirect/op_arrow.md) | 所有するオブジェクトのメンバへアクセスする | C++26 |
| [`valueless_after_move`](indirect/valueless_after_move.md) | 無効値状態かどうかを判定する | C++26 |

### その他

| 名前 | 説明 | 対応バージョン |
|------|------|----------------|
| [`get_allocator`](indirect/get_allocator.md) | アロケータを取得する | C++26 |
| [`swap`](indirect/swap.md) | 他の`indirect`オブジェクトと値を交換する | C++26 |


## メンバ型

| 名前 | 定義 | 対応バージョン |
|------|------|----------------|
| `value_type` | `T` | C++26 |
| `allocator_type` | `Allocator` | C++26 |
| `pointer` | [`allocator_traits`](/reference/memory/allocator_traits.md)`<Allocator>::pointer` | C++26 |
| `const_pointer` | [`allocator_traits`](/reference/memory/allocator_traits.md)`<Allocator>::const_pointer` | C++26 |


## 非メンバ(*Hidden friends*)関数

| 名前 | 説明 | 対応バージョン |
|------|------|----------------|
| [`swap`](indirect/swap_free.md) | 2つの`indirect`オブジェクトを交換する | C++26 |

### 比較演算子

| 名前 | 説明 | 対応バージョン |
|------|------|----------------|
| [`operator==`](indirect/op_equal.md) | 等値比較を行う | C++26 |
| [`operator<=>`](indirect/op_compare_3way.md) | 三方比較を行う | C++26 |

`operator==`から`operator!=`が、`operator<=>`から`operator<` / `operator<=` / `operator>` / `operator>=`が導出される。


## 推論補助

| 名前 | 説明 | 対応バージョン |
|------|------|----------------|
| [`(deduction_guide)`](indirect/op_deduction_guide.md) | クラステンプレートの推論補助 | C++26 |


## ハッシュサポート

| 名前 | 説明 | 対応バージョン |
|------|------|----------------|
| [`hash`](indirect/hash.md) | `hash`クラスの特殊化 | C++26 |


## 例
```cpp example
#include <cassert>
#include <memory>

int main()
{
// 動的確保したintを、値の意味論で保持する
std::indirect<int> a{42};
assert(*a == 42);

// コピーは所有オブジェクトのディープコピー
std::indirect<int> b = a;
*b = 10;
assert(*a == 42); // aは影響を受けない
assert(*b == 10);

// 比較は所有オブジェクトの比較に転送される
assert(a == std::indirect<int>{42});
assert(b < a);
}
```
* std::indirect[color ff0000]

### 出力
```
```


## バージョン
### 言語
- C++26

### 処理系
- [Clang](/implementation.md#clang): 22 [mark noimpl]
- [GCC](/implementation.md#gcc): 16.1 [mark verified]
- [Visual C++](/implementation.md#visual_cpp): 2026 Update 2 [mark noimpl]


## 関連項目
- [`std::polymorphic`](polymorphic.md) 派生型を多態的に保持する値型
- [`std::unique_ptr`](unique_ptr.md) 所有権をもつが参照の意味論をもつスマートポインタ
- [`std::optional`](/reference/optional/optional.md) 動的確保せずに無効値状態を表現する型


## 参照
- [P3019R14 `indirect` and `polymorphic`: Vocabulary Types for Composite Class Design](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3019r14.pdf)
- C++26で`indirect`と`polymorphic`が追加された
39 changes: 39 additions & 0 deletions reference/memory/indirect/get_allocator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# get_allocator
* memory[meta header]
* std[meta namespace]
* indirect[meta class]
* function[meta id-type]
* cpp26[meta cpp]

```cpp
constexpr allocator_type get_allocator() const noexcept;
```

## 概要
このオブジェクトが使用するアロケータを取得する。


## 戻り値
所有するアロケータのコピー。


## 例外
投げない。


## バージョン
### 言語
- C++26

### 処理系
- [Clang](/implementation.md#clang): 22 [mark noimpl]
- [GCC](/implementation.md#gcc): 16.1 [mark verified]
- [Visual C++](/implementation.md#visual_cpp): 2026 Update 2 [mark noimpl]


## 関連項目
- [`std::indirect`](../indirect.md)


## 参照
- [P3019R14 `indirect` and `polymorphic`: Vocabulary Types for Composite Class Design](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3019r14.pdf)
66 changes: 66 additions & 0 deletions reference/memory/indirect/hash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# hash
* memory[meta header]
* std[meta namespace]
* indirect[meta class]
* class template[meta id-type]
* cpp26[meta cpp]

```cpp
namespace std {
template <class T, class Allocator>
struct hash<indirect<T, Allocator>>;
}
```
* hash[link /reference/functional/hash.md]

## 概要
[`std::hash`](/reference/functional/hash.md)クラスの、`std::indirect`に対する特殊化。

この特殊化は、`hash<T>`が有効である場合にのみ有効となる。


## 効果
`indirect<T, Allocator>`型のオブジェクト`i`に対して、`hash<indirect<T, Allocator>>()(i)`は、`i`が無効値状態でなければ`hash<T>()(*i)`と同じ値を返し、無効値状態であれば処理系定義の値を返す。


## 備考
メンバ関数が`noexcept`である保証はない。


## 例
```cpp example
#include <cassert>
#include <functional>
#include <memory>

int main()
{
std::indirect<int> a{42};
// 所有する値のハッシュ値と一致する
assert((std::hash<std::indirect<int>>{}(a) == std::hash<int>{}(42)));
}
```
* std::indirect[color ff0000]
* std::hash[link /reference/functional/hash.md]

### 出力
```
```


## バージョン
### 言語
- C++26

### 処理系
- [Clang](/implementation.md#clang): 22 [mark noimpl]
- [GCC](/implementation.md#gcc): 16.1 [mark verified]
- [Visual C++](/implementation.md#visual_cpp): 2026 Update 2 [mark noimpl]


## 関連項目
- [`std::indirect`](../indirect.md)


## 参照
- [P3019R14 `indirect` and `polymorphic`: Vocabulary Types for Composite Class Design](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3019r14.pdf)
65 changes: 65 additions & 0 deletions reference/memory/indirect/op_arrow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# operator->
* memory[meta header]
* std[meta namespace]
* indirect[meta class]
* function[meta id-type]
* cpp26[meta cpp]

```cpp
constexpr const_pointer operator->() const noexcept; // (1)
constexpr pointer operator->() noexcept; // (2)
```

## 概要
所有するオブジェクトのメンバへアクセスするためのポインタを取得する。


## 事前条件
`*this`が無効値状態でないこと。


## 戻り値
所有するオブジェクトを指すポインタ。


## 例外
投げない。


## 例
```cpp example
#include <cassert>
#include <memory>
#include <string>

int main()
{
std::indirect<std::string> s{std::string{"hello"}};
assert(s->size() == 5); // 所有するstringのメンバにアクセス
s->push_back('!');
assert(*s == "hello!");
}
```
* std::indirect[color ff0000]

### 出力
```
```


## バージョン
### 言語
- C++26

### 処理系
- [Clang](/implementation.md#clang): 22 [mark noimpl]
- [GCC](/implementation.md#gcc): 16.1 [mark verified]
- [Visual C++](/implementation.md#visual_cpp): 2026 Update 2 [mark noimpl]


## 関連項目
- [`std::indirect`](../indirect.md)


## 参照
- [P3019R14 `indirect` and `polymorphic`: Vocabulary Types for Composite Class Design](https://open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3019r14.pdf)
Loading
Loading