最終更新日時(UTC):
が更新

履歴 編集

<ranges>

ranges(C++20)

<ranges> では、イテレータの組ではなく、コンテナや配列、部分的なコンテナなどの範囲(Range)を直接扱うライブラリを提供する。

C++17までは、標準アルゴリズム関数はイテレータの組を扱い、範囲を直接扱ってはいなかった。 このようなライブラリはBoost.Range、range-v3、cpplinqなどで実績があり、C++標準にも取り込まれることになった。

また、従来のイテレータの組は基本的に同じ型であることが期待されていたが、C++20のRangesではendで得られるものは番兵(sentinel)と規定され、イテレータと同じ型でなくてもよくなった。

<ranges>で定義されるコンセプトはイテレータを用いて定義されるものが多い。イテレータや番兵に関するコンセプトなどは引き続き<iterator>で提供される。

また、Range対応版のアルゴリズム関数は引き続き<algorithm>で提供される。

名前空間構造

<ranges>で定義されるものは全てstd::ranges名前空間の下にある。また、各種view型を生成するRangeアダプタ/ファクトリオブジェクトはstd::ranges::views名前空間の下で定義され、std::viewsからもアクセスする事ができる。

名前空間だけを見てみると次のようになっている。

namespace std {
  // 通常のstd名前空間

  namespace ranges {
    // <ranges>のものはここに定義される

    namespace views {
      // Rangeアダプタ/ファクトリオブジェクトが定義される

    }
  }

  // この名前空間エイリアスによって、std::viewsとしてstd::ranges::viewsにアクセスできる
  namespace views = ranges::views;
}

Rangeアクセス

これらの機能は従来<iterator>でフリー関数として提供されていた。 C++20では関数によるカスタマイゼーションポイントの問題点を解消するため、関数オブジェクトとして再実装されている。 互換性を維持するために従来の関数も残っているが、これらのカスタマイゼーションポイントオブジェクトを使用することが推奨される。

名前 説明 対応バージョン
begin Rangeの先頭を指すイテレータを取得する (customization point object) C++20
end Rangeの末尾の次を指すイテレータもしくは番兵を取得する (customization point object) C++20
cbegin Rangeの先頭を指す読み取り専用イテレータを取得する (customization point object) C++20
cend Rangeの末尾の次を指す読み取り専用イテレータもしくは番兵を取得する (customization point object) C++20
rbegin Rangeの末尾を指す逆イテレータを取得する (customization point object) C++20
rend Rangeの先頭の前を指す逆イテレータもしくは番兵を取得する (customization point object) C++20
crbegin Rangeの末尾を指す読み取り専用逆イテレータを取得する (customization point object) C++20
crend Rangeの先頭の前を指す読み取り専用逆イテレータもしくは番兵を取得する (customization point object) C++20
size Rangeの要素数を取得する (customization point object) C++20
ssize Rangeの要素数を、符号付き整数型で取得する (customization point object) C++20
empty Rangeが空かどうかを判定する (customization point object) C++20
data Rangeの要素配列へのポインタを取得する (customization point object) C++20
cdata Rangeの要素配列への読み取り専用ポインタを取得する (customization point object) C++20

Rangeに関連する型へのアクセス

名前 説明 対応バージョン
iterator_t イテレータ型を取得する (alias template) C++20
sentinel_t 番兵型を取得する (alias template) C++20
range_difference_t イテレータの差の型を取得する (alias template) C++20
range_size_t サイズの型を取得する(alias template) C++20
range_value_t 要素の型を取得する (alias template) C++20
range_reference_t 要素の参照型を取得する (alias template) C++20
range_rvalue_reference_t 要素の右辺値参照型を取得する (alias template) C++20

Rangeコンセプト

名前 説明 対応バージョン
range Rangeを定義するコンセプト (concept) C++20
borrowed_range 所有権を持たないRange (concept) C++20
sized_range サイズを償却定数時間で求められるRange (concept) C++20
view ビューであるRange (concept) C++20
output_range イテレータが出力イテレータであるRange (concept) C++20
input_range イテレータが入力イテレータであるRange (concept) C++20
forward_range イテレータが前進イテレータであるRange (concept) C++20
bidirectional_range イテレータが双方向イテレータであるRange (concept) C++20
random_access_range イテレータがランダムアクセスイテレータであるRange (concept) C++20
contiguous_range イテレータが隣接イテレータであるRange (concept) C++20
common_range イテレータと番兵の型が等しいRange (concept) C++20
viewable_range ビューに変換できるRange (concept) C++20

カスタマイゼーションポイント

名前 説明 対応バージョン
enable_borrowed_range Rangeをborrowed_rangeにする (variable template) C++20
enable_view Rangeをviewにする (variable template) C++20
disable_sized_range Rangeをsized_rangeにならないようにする (variable template) C++20

ビューインターフェース

名前 説明 対応バージョン
view_base 基底クラスとすることでviewとなるタグ型 (class) C++20
view_interface ビューの基底クラスとして推奨されるクラス (class template) C++20

部分Range

名前 説明 対応バージョン
subrange_kind 部分Rangeの種類を表す列挙体 (enum class) C++20
subrange イテレータペアをRangeとして扱う型 (class template) C++20

ダングリングイテレータハンドリング

名前 説明 対応バージョン
dangling ダングリングイテレータ、ダングリングRangeを表す型 (class) C++20
borrowed_iterator_t Rangeがborrowed_rangeではないときdanglingとなるイテレータ (alias template) C++20
borrowed_subrange_t Rangeがborrowed_rangeではないときdanglingとなる部分Range (alias template) C++20

Rangeファクトリ

Rangeファクトリは、Rangeではないオブジェクトからviewを生成するものである。 その実体は、引数の無いものは変数テンプレート、引数のあるものは関数テンプレートやカスタマイゼーションポイントオブジェクトとなっている。

empty view

名前 説明 対応バージョン
empty_view 空のRange (class template) C++20
views::empty empty_viewを生成する (variable template) C++20

single view

名前 説明 対応バージョン
single_view 指定した値1つからなるRange (class template) C++20
views::single single_viewを生成する (customization point object) C++20

iota view

名前 説明 対応バージョン
iota_view 単調増加列であるRange (class template) C++20
views::iota iota_viewを生成する (customization point object) C++20

istream view

名前 説明 対応バージョン
basic_istream_view 入力ストリームから値を読むRange (class template) C++20
views::istream_view basic_istream_viewを生成する (function template) C++20

Rangeアダプタ

Rangeアダプタは、既存のRangeに作用して新たなviewを生成するものである。 その実体はカスタマイゼーションポイントオブジェクトとなっている。

RangeアダプタをRangeに作用させる方法には、関数記法とパイプライン記法の2つがある。

RをRangeアダプタ、rを元になるRangeとする。このとき、以下の2つの式は同じviewを生成する。

R(r)   // 関数記法
r | R  // パイプライン記法

Rangeアダプタを適用した結果はview、すなわちRangeであることから、Rangeアダプタを次々と繋いでいくことができる。

R3(R2(R1(r)))     // 関数記法
r | R1 | R2 | R3  // パイプライン記法

Rangeアダプタの処理は遅延評価され、要素は必要になるまで生成されない。このような仕組みは実際の仕事の多くをイテレータが担うことで実現している。

for (auto&& item : r | R) {
  // ループ一回ごとに、(r | R)の要素を1つ生成する。このとき、rの要素を必要なだけ取得する。
}

第1引数にviewable_rangeを受け取ってviewを返すカスタマイゼーションポイントオブジェクトを、Rangeアダプタオブジェクトという。とくに、1引数のものをRangeアダプタクロージャオブジェクトという。

Rangeアダプタオブジェクトadaptorが2つ以上の引数をとる場合、以下の3つの式は等しい。

adaptor(range, args...)
adaptor(args...)(range)
range | adaptor(args...)

このとき、adaptor(args...)はRangeアダプタクロージャオブジェクトになっている。

all view

名前 説明 対応バージョン
ref_view Rangeへの参照として振る舞うビュー (class template) C++20
views::all Rangeへの参照として振る舞うビューを生成する (customization point object) C++20
views::all_t allの戻り値型 (alias template) C++20

filter view

名前 説明 対応バージョン
filter_view 指定した条件を満たす要素だけを集めるビュー (class template) C++20
views::filter filter_viewを生成する (customization point object) C++20

transform view

名前 説明 対応バージョン
transform_view 指定した関数で各要素を変換するビュー (class template) C++20
views::transform transform_viewを生成する (customization point object) C++20

take view

名前 説明 対応バージョン
take_view 先頭から指定した個数だけ取り出すビュー (class template) C++20
views::take 先頭から指定した個数だけ取り出すビューを生成する (customization point object) C++20

take while view

名前 説明 対応バージョン
take_while_view 先頭から指定した条件を満たす範囲を取り出すビュー (class template) C++20
views::take_while take_while_viewを生成する (customization point object) C++20

drop view

名前 説明 対応バージョン
drop_view 先頭から指定した個数だけ除外するビュー (class template) C++20
views::drop 先頭から指定した個数だけ除外するビューを生成する (customization point object) C++20

drop while view

名前 説明 対応バージョン
drop_while_view 先頭から指定した条件を満たす範囲を除外するビュー (class template) C++20
views::drop_while drop_while_viewを生成する (customization point object) C++20

join view

名前 説明 対応バージョン
join_view ネストされたRangeを平坦にするビュー (class template) C++20
views::join ネストされたRangeを平坦にするビューを生成する (customization point object) C++20

split view

名前 説明 対応バージョン
lazy_split_view Rangeを指定したデリミタで分割するビュー (class template) C++20
views::lazy_split lazy_split_viewを生成する (customization point object) C++20
split_view 文字列分割に特化したlazy_split_view (class template) C++20
views::split split_viewを生成する (customization point object) C++20

counted view

名前 説明 対応バージョン
views::counted イテレータから指定した数の範囲をRangeとして扱うビューを生成する (customization point object) C++20

common view

名前 説明 対応バージョン
common_view common_rangeにしたビュー (class template) C++20
views::common common_rangeなビューを生成する (customization point object) C++20

reverse view

名前 説明 対応バージョン
reverse_view 逆順のビュー (class template) C++20
views::reverse 逆順のビューを生成する (customization point object) C++20

elements view

名前 説明 対応バージョン
elements_view 第n要素を集めたビュー (class template) C++20
keys_view 第0要素を集めたビュー (alias template) C++20
values_view 第1要素を集めたビュー (alias template) C++20
views::elements elements_viewを生成する (customization point object) C++20
views::keys keys_viewを生成する (customization point object) C++20
views::values values_viewを生成する (customization point object) C++20

バージョン

言語

  • C++20

処理系

関連項目

参照