subrange
クラス (C++ 標準ライブラリ)
開始反復子とセンチネルによって定義されている範囲の要素の一部のビューを提供します。
構文
template<input_or_output_iterator I, sentinel_for<I> S, subrange_kind K>
requires (K == subrange_kind::sized || !sized_sentinel_for<S, I>)
class subrange : public view_interface<subrange<I, S, K>>
テンプレート パラメーター
I
開始反復子の型。 input_or_output_iterator
の概念により、I
がすべての要素を読み取ることができる反復子であることが保証されます。
K
サブ範囲の種類: subrange_kind::sized
を使用して、サイズの大きなサブ範囲を指定します。 反復子とセンチネルを減算してサイズを生成できる場合は、 sized_sentinel_for<S, I>
を使用します。 サブ範囲オブジェクトsubrange_kind::sized || !sized_sentinel_for<S, I>
ローカルにサイズを格納する必要があります。サブ範囲を作成するには、(ここではsubrange_kind::sized
を指定する) sized_range
を受け取るコンストラクターを使用するか、iterator
、sentinel
、size
を受け取るコンストラクターを使用してサブ範囲を構築する必要があります (ここでsized_sentinel_for<S, I>
を指定します)。
S
終了反復子の型。 sized_sentinel_for
の概念により、S
をI
のセンチネルとして使用できることと、I
内の現在の反復子位置との間の距離を一定の時間で計算することが可能になります。
特性の表示
以下の項目の説明については、 View クラスの特性を参照してください。
特徴 | 説明 |
---|---|
範囲アダプター | views::counted |
基になる範囲 | 任意の範囲 |
要素の種類 | iter_reference_t<I> |
反復子カテゴリの表示 | I カテゴリと同じです |
サイズ | K が subrange::sized の場合 |
const 対応 |
I がコピー可能な場合 |
共通範囲 | I とS が同じ型の場合。 |
借用範囲 | はい |
メンバー
メンバー関数 | 説明 |
---|---|
コンストラクターC++20 | subrange を構築します。 |
operator PairLike C++20 |
subrange をペアのような型に変換します。 |
advance C++20 |
反復子を指定した距離に移動します。 |
begin |
最初の要素を指す反復子を取得します。 |
empty C++20 |
subrange が空かどうかをテストします。 |
end C++20 |
subrange の最後に sentinel を取得します。 |
next C++20 |
この subrange のコピーを作成しますが、格納されている反復子を指定した距離を前方に移動します。 |
prev C++20 |
この subrange のコピーを作成しますが、格納されている反復子を指定した距離に戻します。 |
size C++20 |
要素の数を取得します。 |
継承の対象 view_interface |
説明 |
back C++20 |
最後の要素を取得します。 |
data C++20 |
最初の要素へのポインターを取得します。 |
front C++20 |
最初の要素を取得します。 |
operator[] C++20 |
指定した位置にある要素を取得します。 |
operator bool C++20 |
subrange が空かどうかをテストします。 |
解説
subrange
は、開始反復子と終了反復子があるが、代わりに 1 つのオブジェクトを渡す場合に便利です。 たとえば、範囲アダプターを呼び出したいが、開始反復子と終了反復子がある場合は、 subrange
を使用してそれらをラップし、 subrange
を範囲アダプターに渡すことができます。
要件
Header: <ranges>
(C++20 以降)
名前空間: std::ranges
コンパイラ オプション: /std:c++20
以降が必要です。
コンストラクター
subrange
を作成する。
1) subrange() requires default_initializable<I> = default;
2) template <Convertible_to_non_slicing<I> It>
constexpr subrange(It begin, S end) requires (!Store_size);
3) template <Convertible_to_non_slicing<I> It>
constexpr subrange(It begin, S end, const Size_type size) requires (K == subrange_kind::sized);
4) template <Not_same_as<subrange> rg>
requires borrowed_range<rg>
&& Convertible_to_non_slicing<iterator_t<rg>, I>
&& convertible_to<sentinel_t<rg>, S>
constexpr subrange(rg&& r) requires (!_Store_size || sized_range<rg>);
5) template <borrowed_range rg>
requires Convertible_to_non_slicing<iterator_t<rg>, I> && convertible_to<sentinel_t<rg>, S>
constexpr subrange(rg&& r, const _Size_type sizeHint) requires (K == subrange_kind::sized)
パラメーター
begin
サブ範囲の最初の要素を指す反復子。
end
サブ範囲の末尾を指す Sentinel。 指す要素はサブ範囲に含まれません。
sizeHint
要素の範囲のサイズ。 これは、size
メンバー関数を最適化するために使用されます。これは、型がsized_sentinel_for
をモデル化していない反復子とセンチネルからサイズ変更されたsubrange
を作成する場合に必要です。
テンプレート パラメーターの型の詳細については、「 Template パラメーターを参照してください。
戻り値
subrange
のインスタンス。
解説
1) 既定では、格納されている反復子とセンチネルを構築します。 サイズ ヒントは 0 に設定されます。
2) std::move()
を使用して、 begin
反復子と end
sentinel を格納されている反復子とセンチネルに移動します。
3) 格納されている反復子を std::move(begin)
で初期化し、 std::move(end)
を使用して格納されたセンチネルを初期化し、格納されたサイズ ヒントを size
で初期化します。これは、1 番目と 2 番目の引数の間の距離と等しい必要があります。
4) 範囲から subrange
を構築します。
5) szHint != ranges::distance(rg)
場合、動作は定義されません。
counted
範囲アダプターは、subrange
を作成できます。 そのアダプターは、開始反復子とカウントを受け取ります。
例: counted
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto pos5 = std::ranges::find(v, 5);
auto countedView = std::views::counted(pos5, 5);
for (auto e : countedView) // outputs 5 6 7 8 9
{
std::cout << e << ' ';
}
std::cout << '\n';
// You can pass the range directly if it supports input_or_output_iterator, in which case, the
// count starts from the first element
const char chars[] = { 'H','i',' ','t','h','e','r','e' };
for (char c : std::views::counted(chars, 2))
{
std::cout << c; // outputs Hi
}
}
5 6 7 8 9
Hi
operator PairLike
subrange
を、pair-like
モデル化する型に変換します。
template<not-same-as<subrange> PairLike>
requires pair-like-convertible-from<PairLike, const I&, const S&>
constexpr operator PairLike() const;
パラメーター
ありません。
テンプレート パラメーターの型の詳細については、「 Template パラメーターを参照してください。
戻り値
格納されている反復子と sentinel を使用して直接初期化される PairLike
値。
ペアの最後の値がセンチネルになります。
次の例に示すように、sentinel は past サブ範囲の最後の要素であることを忘れないでください。
解説
この変換は、範囲を示すために (最初、最後の) ペアを受け入れる古い Boost::Ranges
コードで役立ちます。
この変換は、サブ範囲を pair
または tuple
、またはモデル化 pair_like
その他の型に変換する場合に便利です。 pair_like
型の例を次に示します。
std::array<T, 2>
std::pair<T, U>
std::ranges::subrange<I, S, K>
std::tuple<T, U>
例: operator PairLike()
// requires /std:c++20 or later
#include <iostream>
#include <ranges>
#include <vector>
#include <utility>
int main()
{
constexpr int a[] = {0, 1, 2, 3, 4, 5};
std::ranges::subrange rg(a);
rg.advance(2);
const std::pair<const int*, const int*> p = rg;
for (auto e : rg)
{
std::cout << e << ' ';
}
// because the sentinel points after the last element, subtract one to get the last element
std::cout << '\n' << *p.first << ':' << *(p.second - 1) << '\n'; // outputs 2:5
}
2 3 4 5
2:5
advance
要素をn
して、このsubrange
の反復子を調整します。
constexpr subrange& advance(const iter_difference_t<I> n);
パラメーター
n
反復子を調整する要素の数。 n
は正 (前に進む) か、 I
が双方向の場合は負 (後方に移動) できます。
解説
この関数は、 subrange
内の反復子の現在の状態を変更します。
subrange
の末尾を超えて進む場合、反復子はsubrange
の末尾にある sentinel に設定されます。
(負のn
を使用して) subrange
の先頭を超えた場合、subrange
を作成した範囲に要素がない場合は、無効なパラメーター例外が発生します。
例 advance
// requires /std:c++20 or later
#include <iostream>
#include <ranges>
#include <string>
#include <vector>
void print(const std::string &msg, auto &&v)
{
std::cout << msg << '\n';
for (auto& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
std::vector v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
print("Original vector: ", v); // outputs 0 1 2 3 4 5 6 7 8 9 10
// create a subrange 3 4 5 6
std::ranges::subrange theSubrange{ std::ranges::find(v,3), std::ranges::find(v, 7) };
print("The subrange: ", theSubrange); // outputs 3 4 5 6
auto sr = theSubrange.advance(2); // get a subrange 2 positions to the right of the current iterator location
print("theSubrange.advance(2): ", sr); // outputs 5 6
print("Note that subrange's iterator moved during advance(): ", sr); // outputs 5 6
sr = theSubrange.advance(-3); // Moving before the subrange, but onto a valid element in the original range
print("theSubrange.advance(-3): ", sr); // outputs 2 3 4 5 6
}
Original vector:
0 1 2 3 4 5 6 7 8 9 10
The subrange:
3 4 5 6
theSubrange.advance(2):
5 6
Note that subrange's iterator moved during advance():
5 6
theSubrange.advance(-3):
2 3 4 5 6
begin
subrange
内の最初の要素を指す反復子を取得します。
1) constexpr I begin() const requires copyable<I>;
2) [[nodiscard]] constexpr I begin() requires (!std::copyable<I>);
パラメーター
ありません。
戻り値
subrange
内の最初の要素を指す反復子。
反復子がコピーできない場合は、 std::move()
で返されます。 反復子が移動された場合、格納されている反復子の状態は、 I
の移動コンストラクターの実装によって異なります。
empty
subrange
が空かどうかをテストします。
constexpr bool empty() const;
パラメーター
ありません。
戻り値
subrange
に要素がない場合は、true
を返します。 それ以外の場合、false
を返します。
end
の最後にセンチネルを取得します。 subrange
[[nodiscard]] constexpr S end() const;
パラメーター
ありません。
戻り値
subrange
の最後の要素に続く sentinel:
センチネルは、保存されたセンチネルからコピーして構築されます。
next
この subrange
のコピーを作成しますが、格納されている反復子を指定した距離を前方に移動します。
1) [[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) const & requires forward_iterator<I>;
2) [[nodiscard]] constexpr subrange next(iter_difference_t<I> n = 1) &&;
パラメーター
n
反復子を前方に移動する要素の数。 デフォルト値は 1 です。 正の値を指定する必要があります。
戻り値
*n
*th 要素から始まるsubrange
のコピーを返します。
解説
advance()
とは異なり、next()
は元のsubrange
に格納されている反復子の場所を変更しません。
返された subrange
には、元のサブ範囲に含まれるすべての要素がありますが、反復子は別の場所にあります。
1) 戻り値は次と同じです。
auto tmp = *this;
tmp.advance(n);
return tmp;
2) 戻り値は次と同じです。
advance(n);
return std::move(*this);
例: next
// requires /std:c++20 or later
#include <iostream>
#include <ranges>
#include <string>
#include <vector>
void print(const std::string &msg, auto &&v)
{
std::cout << msg << '\n';
for (auto& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
std::vector v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
print("Original vector:", v); // 0 1 2 3 4 5 6 7 8 9 10
// create a subrange from the front of v up to (but not including) the element 7
std::ranges::subrange theSubrange{ std::ranges::find(v,1), std::ranges::find(v, 7) };
print("The subrange:", theSubrange); // 1 2 3 4 5 6
auto forward = theSubrange.advance(3); // get a subrange 3 positions to the right of the current iterator location
print("theSubrange.advance(3):", forward); // 4 5 6
// prev()
auto previous = theSubrange.prev(2); // move back 2
print("theSubrange.prev(2):", previous); // 2 3 4 5 6
print("Note that the subrange's iterator did *not* move during prev():", theSubrange); // 4 5 6
}
Original vector:
0 1 2 3 4 5 6 7 8 9 10
The subrange:
1 2 3 4 5 6
theSubrange.next(3):
4 5 6
Note that the original subrange's iterator did *not* move during next():
1 2 3 4 5 6
prev
この subrange
のコピーを作成しますが、格納されている反復子を指定した距離に戻します。
[[nodiscard]] constexpr subrange prev(std::iter_difference_t<I> n = 1 ) const
requires std::bidirectional_iterator<I>;
パラメーター
n
反復子を戻す要素の数。 デフォルト値は 1 です。 正の値を指定する必要があります。
戻り値
subrange
のコピーを返しますが、反復子を要素n
戻します。
解説
advance()
とは異なり、prev()
は元のsubrange
に格納されている反復子の場所を変更しません。
返された subrange
には元のサブ範囲に含まれるすべての要素がありますが、反復子は別の場所にあります。 戻り値は次のように考えることができます。
auto tmp = *this;
tmp.advance(-n);
return tmp;
例 prev
// requires /std:c++20 or later
#include <iostream>
#include <ranges>
#include <string>
#include <vector>
void print(const std::string &msg, auto &&v)
{
std::cout << msg << '\n';
for (auto& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
std::vector v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
print("Original vector:", v); // 0 1 2 3 4 5 6 7 8 9 10
// create a subrange from the front of v up to (but not including) the element 7
std::ranges::subrange theSubrange{std::ranges::find(v,1), std::ranges::find(v, 7)};
print("The subrange: ", theSubrange); // 1 2 3 4 5 6
auto forward = theSubrange.advance(3); // get a subrange 3 positions to the right of the current iterator location
print("theSubrange.advance(3):", forward); // 4 5 6
// prev()
auto previous = theSubrange.prev(2); // move back 2
print("theSubrange.prev(2):", previous); // 2 3 4 5 6
print("Note that the subrange's iterator did *not* move during prev():", theSubrange); // 4 5 6
}
Original vector:
0 1 2 3 4 5 6 7 8 9 10
The subrange:
1 2 3 4 5 6
theSubrange.advance(3):
4 5 6
theSubrange.prev(2):
2 3 4 5 6
Note that the subrange's iterator did *not* move during prev():
4 5 6
size
subrange
内の要素の数を取得します。
constexpr size() const
requires (K == ranges::subrange_kind::sized);
パラメーター
ありません。
戻り値
subrange
にある要素の数。
サイズが格納されていない場合(K == ranges::subrange_kind::sized
指定されたsubrange
が作成され、std::sized_sentinel_for<S, I>
が満たされていない場合)、サイズは開始反復子と終了反復子の間の距離として返されます。
たとえば、advance
を使用してbegin
反復子の位置を変更すると、報告されるサイズが変更されます。