最終更新日時: 2026年01月21日 22時43分46秒 (JST)
yoh が更新

履歴 編集

class template
<mdspan>

# std::mdspan(C++23)

    namespace std {
      template<
        class ElementType,
        class Extents,
        class LayoutPolicy = layout_right,
        class AccessorPolicy = default_accessor<ElementType>>
      class mdspan;
    }

## 概要

`mdspan`は、任意のメモリブロックに対して多次元配列のようにアクセスする機能を提供するクラスである。 `mdspan`それ自体は参照先メモリブロックを所有せず、`[]`演算子を介して多次元配列のように見せかけるビュー(view)にすぎない。

クラスの名称`mdspan`は、1次元の範囲`std::span`に対する多次元(MultiDimensional)拡張に由来する。

`mdspan`の特殊化`MDS`は`copyable`のモデルであり、かつ

- `is_nothrow_move_constructible_v<MDS>`が`true`、かつ
- `is_nothrow_move_assignable_v<MDS>`が`true`、かつ
- `is_nothrow_swappable_v<MDS>`が`true`となる。

そのメンバ型`accessor_type`, `mapping_type`, `pointer`がトリビアルコピー可能であるとき、`mdspan`の特殊化もトリビアルコピー可能である。

### テンプレートパラメータ

`mdspan`クラスでは、テンプレートパラメータを介して多次元配列ビューをカスタマイズできる。

- `ElementType` : 多次元配列ビューの要素型
- `Extents` : 多次元配列の次元数(rank)と要素数(extent)
- `LayoutPolicy` : 多次元配列インデクスと要素位置の対応関係
- `AccessorPolicy` : 要素アクセス時の詳細挙動

### 説明専用メンバ変数

`mdspan`クラスは、下記の説明専用メンバ変数を保持する。

- `acc_` : `accessor_type`型の要素アクセサ
- `map_` : `mapping_type`型のレイアウトマッピング
- `ptr_` : `data_handle_type`型のメモリブロックへのハンドル（ポインタ）

## 適格要件

- `ElementType`は抽象クラス型もしくは配列型のいずれでもない完全型であり、かつ
- `Extents`は`extents`の特殊化であり、かつ
- `is_same_v<ElementType, typename AccessorPolicy::element_type>`が`true`であること。

`LayoutPolicy`はレイアウトマッピングポリシー要件を満たし、かつ`AccessorPolicy`はアクセサポリシー要件を満たすこと。

## メンバ関数

### 構築・破棄

名前 | 説明 | 対応バージョン
--- | --- | ---
`(constructor)` | コンストラクタ | C++23
`(destructor)` | デストラクタ | C++23
`operator=` | 代入演算子 | C++23

### 要素へのアクセス

名前 | 説明 | 対応バージョン
--- | --- | ---
`operator[]` | 多次元配列の要素アクセス | C++23
`at` | 多次元配列の要素アクセス | C++26

### 多次元配列サイズ

名前 | 説明 | 対応バージョン
--- | --- | ---
`rank` | 多次元配列の次元数を取得する | C++23
`rank_dynamic` | 多次元配列のうち動的要素数に指定された次元数を取得する | C++23
`static_extent` | 指定次元の静的要素数を取得する | C++23
`extent` | 指定次元の要素数を取得する | C++23
`size` | 多次元インデクス空間のサイズを取得する | C++23
`empty` | 多次元インデクス空間がサイズ0か否かを取得する | C++23

### メンバ変数アクセサ

名前 | 説明 | 対応バージョン
--- | --- | ---
`extents` | 多次元配列のサイズを取得する | C++23
`data_handle` | メモリブロックへのハンドル`ptr_`を取得する | C++23
`mapping` | レイアウトマッピング`map_`を取得する | C++23
`accessor` | 要素アクセサ`acc_`を取得する | C++23

### レイアウトマッピング

名前 | 説明 | 対応バージョン
--- | --- | ---
`is_always_unique()` | `mapping_type::is_always_unique()` | C++23
`is_always_exhaustive()` | `mapping_type::is_always_exhaustive()` | C++23
`is_always_strided()` | `mapping_type::is_always_strided()` | C++23
`is_unique()` | `map_.is_unique()` | C++23
`is_exhaustive()` | `map_.is_exhaustive()` | C++23
`is_strided()` | `map_.is_strided()` | C++23
`stride(rank_type r)` | `map_.stride(r)` | C++23

## メンバ型

名前 | 説明 | 対応バージョン
--- | --- | ---
`extents_type` | 多次元配列サイズ型`Extents` | C++23
`layout_type` | レイアウトマッピングポリシー型`LayoutPolicy` | C++23
`accessor_type` | アクセサポリシー型`AccessorPolicy` | C++23
`mapping_type` | レイアウトマッピング型`LayoutPolicy::mapping<Extents>` | C++23
`element_type` | 要素型`ElementType` | C++23
`value_type` | 要素の値型`remove_cv_t<ElementType>` | C++23
`size_type` | `Extents::size_type` | C++23
`rank_type` | `Extents::rank_type` | C++23
`pointer` | `AccessorPolicy::pointer` | C++23
`reference` | `AccessorPolicy::reference` | C++23

## 非メンバ（Hidden friends）関数

名前 | 説明 | 対応バージョン
--- | --- | ---
`swap` | 2つのオブジェクトを入れ替える | C++23

## 推論補助

名前 | 説明 | 対応バージョン
--- | --- | ---
`(deduction_guide)` | クラステンプレートの推論補助 | C++23

## 例

    #include <mdspan>
    #include <print>

    int main()
    {
      double arr[] = {1, 2, 3, 4, 5, 6};
      // メモリブロックに対する2x3要素の2次元配列ビューを作成
      using Ext2x3 = std::extents<size_t, 2, 3>;
      std::mdspan<double, Ext2x3> mat{arr};

      // 2次元配列の各要素を表示
      for (size_t i = 0; i < mat.extent(0); ++i) {
        for (size_t j = 0; j < mat.extent(1); ++j) {
          std::print("{} ", mat[i, j]);
        }
        std::println("");
      }
    }

### 出力

    1 2 3
    4 5 6

## バージョン

### 言語

- C++23

### 処理系

- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: ??

## 関連項目

- `extents`
- LayoutMappingPolicy
- AccessorPolicy
- C++23 添字演算子の多次元サポート

## 参照

- P0009R18 MDSPAN
- P2599R2 `index_type` & `size_type` in `mdspan`
- P2604R0 `mdspan`: rename `pointer` and `contiguous`
- P2613R1 Add the missing `empty` to `mdspan`
- P3383R3 mdspan.at()
  - C++26で`at`メンバ関数を追加