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

履歴 編集

function
<ranges>

std::ranges::subrange::コンストラクタ(C++20)

// (1)
subrange() = default;

// (2)
constexpr subrange(convertible-to-non-slicing<I> auto i, S s) requires (!StoreSize);

// (3)
constexpr subrange(convertible-to-non-slicing<I> auto i, S s, make-unsigned-like-t<iter_difference_t<I>> n)
  requires (K == subrange_kind::sized);

// (4)
template<different-from<subrange> R>
  requires borrowed_range<R> && convertible-to-non-slicing<iterator_t<R>, I> && convertible_to<sentinel_t<R>, S>
constexpr subrange(R&& r) requires (!StoreSize || sized_range<R>);

// (5)
template<borrowed_range R>
  requires convertible-to-non-slicing<iterator_t<R>, I> && convertible_to<sentinel_t<R>, S>
constexpr subrange(R&& r, make-unsigned-like-t<iter_difference_t<I>> n)
  requires (K == subrange_kind::sized) : subrange{ranges::begin(r), ranges::end(r), n} {}

概要

  • (1) : 空のsubrangeを構築する(デフォルトコンストラクタ)
  • (2) : イテレータiと番兵sが表すイテレータ範囲[i, s)で初期化する
  • (3) : イテレータiと番兵sが表すイテレータ範囲[i, s)で初期化し、subrangeの長さをnにする
  • (4) : 範囲 r で初期化する
  • (5) : 範囲 r で初期化し、subrangeの長さをnにする ((3)へ委譲)

テンプレートパラメータ制約

StoreSizeは次のように定義される説明専用メンバである。

static constexpr bool StoreSize = (K == subrange_kind::sized && !sized_sentinel_for<S, I>);

StoreSizeは、元のRangeから長さを求められないが、長さを別に指定することでsubrangesized_rangeにした場合に真となる。

  • (1): Iデフォルト構築可能であること
  • (2), (4): subrangesizedではない。または、元のRangeから長さを求められる
  • (3), (5): subrangesizedであり、元のRangeから長さを求められない
  • (4): 範囲は構築するsubrangeと同じ型ではない (つまり、(4)はムーブコンストラクタではない)

事前条件

  • (2): [i, s)は有効なイテレータ範囲であること
  • (3): [i, s)は有効なイテレータ範囲であり、nはその範囲の長さ(ranges::distance(i, s))と等しいこと
  • (4): rは有効な範囲であること
  • (5): rは有効な範囲であり、nはその範囲の長さと等しいこと

効果

subrangeが内部で保持するイテレータと番兵を与えられた範囲で初期化する。 さらに、StoreSizeが真のときは大きさを与えられた値で初期化する。

備考

subrangeはコピー、ムーブ可能である。また、テンプレート引数が異なるsubrangeからは、(4)によって構築できる。

#include <cassert>
#include <ranges>
#include <forward_list>
#include <array>

int main()
{
  constexpr std::ranges::subrange<int*, int*, std::ranges::subrange_kind::sized> sub1;
  static_assert(sub1.empty());

  constexpr std::array arr= {1, 2, 3};
  const std::ranges::subrange sub2(arr.begin(), arr.begin() + 1);
  assert(sub2.size() == 1);

  const std::forward_list fwl = {1, 2, 3};
  const std::ranges::subrange sub3(fwl.begin(), ++fwl.begin(), 1);
  // forward_listはsized_rangeではないが、長さを指定しているのでsubrangesized_rangeとなり、sizeメンバ関数が定義される
  static_assert(std::ranges::sized_range<decltype(sub3)>);
  assert(sub3.size() == 1);

  const std::ranges::subrange sub4 = arr;
  assert(sub4.size() == 3);

  const std::ranges::subrange sub5(fwl, 3);
  // forward_listはsized_rangeではないが、長さを指定しているのでsubrangesized_rangeとなり、sizeメンバ関数が定義される
  static_assert(std::ranges::sized_range<decltype(sub5)>);
  assert(sub4.size() == 3);
}

出力

バージョン

言語

  • C++20

処理系

参照