次の方法で共有


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を受け取るコンストラクターを使用するか、iteratorsentinelsizeを受け取るコンストラクターを使用してサブ範囲を構築する必要があります (ここでsized_sentinel_for<S, I>を指定します)。

S
終了反復子の型。 sized_sentinel_forの概念により、SIのセンチネルとして使用できることと、I内の現在の反復子位置との間の距離を一定の時間で計算することが可能になります。

特性の表示

以下の項目の説明については、 View クラスの特性を参照してください。

特徴 説明
範囲アダプター views::counted
基になる範囲 任意の範囲
要素の種類 iter_reference_t<I>
反復子カテゴリの表示 Iカテゴリと同じです
サイズ Ksubrange::sized の場合
const対応 Iがコピー可能な場合
共通範囲 ISが同じ型の場合。
借用範囲 はい

メンバー

メンバー関数 説明
コンストラクターC++20 subrange を構築します。
operator PairLikeC++20 subrangeをペアのような型に変換します。
advanceC++20 反復子を指定した距離に移動します。
begin 最初の要素を指す反復子を取得します。
emptyC++20 subrange が空かどうかをテストします。
endC++20 subrangeの最後に sentinel を取得します。
nextC++20 この subrange のコピーを作成しますが、格納されている反復子を指定した距離を前方に移動します。
prevC++20 この subrange のコピーを作成しますが、格納されている反復子を指定した距離に戻します。
sizeC++20 要素の数を取得します。
継承の対象 view_interface 説明
backC++20 最後の要素を取得します。
dataC++20 最初の要素へのポインターを取得します。
frontC++20 最初の要素を取得します。
operator[]C++20 指定した位置にある要素を取得します。
operator boolC++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の移動コンストラクターの実装によって異なります。

要素 10、20、30 を持つベクトルの図。最初の要素には 10 が含まれており、begin() というラベルが付いています。最後の要素には 30 が含まれており、

empty

subrange が空かどうかをテストします。

constexpr bool empty() const;

パラメーター

ありません。

戻り値

subrangeに要素がない場合は、trueを返します。 それ以外の場合、false を返します。

end

の最後にセンチネルを取得します。 subrange

[[nodiscard]] constexpr S end() const;

パラメーター

ありません。

戻り値

subrangeの最後の要素に続く sentinel:

要素 10、20、30 を持つベクトルの図。最初の要素には 10 が含まれており、begin() というラベルが付いています。最後の要素には 30 が含まれており、

センチネルは、保存されたセンチネルからコピーして構築されます。

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反復子の位置を変更すると、報告されるサイズが変更されます。

関連項目

<ranges>
counted
クラスの表示