[C++] <ranges>のviewを見る14 - counted view

1 min read読了の目安(約1100字

counted view

counted viewは元となるシーケンスの先頭から指定された個数の要素のシーケンスを生成するViewです。

#include <ranges>

int main() {
  auto iota = std::views::iota(1);
  
  for (int n : std::views::counted(std::ranges::begin(iota), 5)) {
    std::cout << n; // 12345
  }
}

このcounted viewstd::ranges::couted_viewのようなクラスがあるわけではなく、生成するにはstd::views::countedを使用します。views::countedはカスタマイぜーションポイントオブジェクトであり、イテレータと生成するViewの要素数を受け取ってその種別によって、指定された数の要素を参照するstd::spanstd::subrangeを返します。
ただ、views::countedrange adaptor objectではないのでパイプラインスタイルで使用することはできません。

take_viewとの差異

counted viewはまさにtake_viewと同じことをしてくれますが、微妙に違いがあります。

  • take_viewViewを受けるが、counted viewはイテレータを受け取る
  • counted viewはオーバラン防止のためのケアをしない
int main() {
  int arr[] = {1, 2, 3};

  // 範囲を飛び越す!
  for (int n : std::views::counted(std::ranges::begin(arr), 5)) {
    std::cout << n;
  }
}

counted viewはイテレータに対してtake_view相当のものを生成するための入り口であり、イテレータ一つではその範囲の終端は分からないのでオーバーランを防ぐことができないのです。