Bagikan melalui


subrange kelas (Pustaka Standar C++)

Menyediakan tampilan bagian dari elemen rentang seperti yang didefinisikan oleh iterator dan sentinel awal.

Sintaks

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>>

Parameter template

I
Jenis iterator mulai. Konsep ini input_or_output_iterator memastikan bahwa I adalah iterator yang dapat membaca semua elemen.

K
Jenis subjudul: Gunakan subrange_kind::sized untuk menentukan subrange berukuran. Gunakan sized_sentinel_for<S, I> jika iterator dan sentinel dapat dikurangi untuk menghasilkan ukuran. Persyaratan subrange_kind::sized || !sized_sentinel_for<S, I> menyimpan ukuran secara lokal dalam objek subrange, dan mengharuskan Anda membangun subrange baik menggunakan konstruktor yang mengambil sized_range (yang akan Anda tentukan subrange_kind::sized di sini) atau melalui konstruktor yang mengambil iterator, , sentineldan size (sehingga Anda akan menentukan sized_sentinel_for<S, I> di sini).

S
Jenis iterator akhir. Konsep ini sized_sentinel_for memastikan bahwa S dapat digunakan sebagai sentinel untuk I dan bahwa dimungkinkan untuk menghitung jarak antara sentinel dan posisi iterator saat ini dalam I waktu konstan.

Melihat karakteristik

Untuk deskripsi entri berikut, lihat Menampilkan karakteristik kelas

Karakteristik Deskripsi
Adaptor rentang views::counted
Rentang yang mendasar Rentang apa pun
Jenis elemen iter_reference_t<I>
Lihat kategori iterator Sama seperti Ikategori s
Ukuran Jika K adalah subrange::sized
Apakah const-iterable Jika I dapat disalin
Rentang umum Jika I dan S adalah jenis yang sama.
Rentang yang dipinjam Ya

Anggota

Fungsi anggota Keterangan
KonstruktorC++20 subrangeBuat .
operator PairLikeC++20 subrange Mengonversi ke jenis seperti pasangan.
advanceC++20 Pindahkan iterator jarak yang ditentukan.
begin Dapatkan iterator ke elemen pertama.
emptyC++20 Uji apakah subrange kosong.
endC++20 Dapatkan sentinel di akhir subrange.
nextC++20 Membuat salinan ini subrange tetapi dengan iterator tersimpan bergerak maju jarak yang ditentukan.
prevC++20 Membuat salinan ini subrange tetapi dengan iterator tersimpan memindahkan kembali jarak yang ditentukan.
sizeC++20 Dapatkan jumlah elemen.
Diwariskan dari view_interface Keterangan
backC++20 Dapatkan elemen terakhir.
dataC++20 Dapatkan penunjuk ke elemen pertama.
frontC++20 Dapatkan elemen pertama.
operator[]C++20 Dapatkan elemen pada posisi yang ditentukan.
operator boolC++20 Uji apakah subrange kosong.

Keterangan

A subrange berguna ketika Anda memiliki iterator awal dan akhir, tetapi Anda ingin meneruskan satu objek sebagai gantinya. Misalnya, jika Anda ingin memanggil adaptor rentang tetapi telah memulai dan mengakhiri iterator, Anda dapat menggunakan subrange untuk membungkusnya dan meneruskan subrange ke adaptor rentang.

Persyaratan

Header: <ranges> (sejak C++20)

kumpulan nama XML: std::ranges

Opsi Pengkompilasi: /std:c++20 atau yang lebih baru diperlukan.

Konstruktor

Buat 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)

Parameter

begin
Iterator yang menunjuk ke elemen pertama dalam subrange.

end
Sentinel yang menunjuk ke akhir subrange. Elemen yang ditunjukkannya tidak disertakan dalam subrange.

sizeHint
Ukuran rentang dalam elemen. Ini digunakan untuk mengoptimalkan size fungsi anggota dan diperlukan jika Anda ingin membuat ukuran subrange dari iterator dan sentinel yang jenisnya tidak model sized_sentinel_for.

Untuk informasi tentang jenis parameter templat, lihat Parameter templat.

Nilai hasil

Instans subrange.

Keterangan

1) Default membangun iterator dan sentinel yang disimpan. Petunjuk ukuran diatur ke 0.
2) Menggunakan std::move() untuk memindahkan iterator begin dan end sentinel ke iterator dan sentinel yang disimpan.
3) Menginisialisasi iterator tersimpan dengan std::move(begin), sentinel tersimpan dengan std::move(end), dan petunjuk ukuran tersimpan dengan , yang harus sama dengan sizejarak antara argumen pertama dan kedua.
4) Buat subrange dari rentang.
5) Perilaku tidak ditentukan jika szHint != ranges::distance(rg).

counted Adaptor rentang dapat membuat subrange. Adaptor itu mengambil iterator awal dan hitungan.

Contoh: 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 Mengonversi ke jenis yang memodelkan pair-like.

template<not-same-as<subrange> PairLike>
requires pair-like-convertible-from<PairLike, const I&, const S&>
constexpr operator PairLike() const;

Parameter

Tidak ada.

Untuk informasi tentang jenis parameter templat, lihat Parameter templat.

Nilai hasil

PairLike Nilai yang diinisialisasi langsung dengan iterator dan sentinel yang disimpan. Nilai terakhir dalam pasangan adalah sentinel.

Ingatlah bahwa sentinel melewati elemen terakhir dalam subrange, seperti yang ditunjukkan pada contoh di bawah ini.

Keterangan

Konversi ini berguna dengan kode lama Boost::Ranges yang menerima pasangan (pertama, terakhir) untuk menunjukkan rentang.
Konversi ini berguna untuk mengonversi subrange ke pair atau tuple atau jenis lain yang memodelkan pair_like. Beberapa contoh jenisnya pair_like adalah:

std::array<T, 2>
std::pair<T, U>
std::ranges::subrange<I, S, K>
std::tuple<T, U>

Contoh: 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

Sesuaikan iterator untuk ini subrange dengan n elemen.

constexpr subrange& advance(const iter_difference_t<I> n);

Parameter

n
Berapa banyak elemen untuk menyesuaikan iterator. n dapat positif (bergerak maju) atau, jika I dua arah, negatif (bergerak mundur).

Keterangan

Fungsi ini memodifikasi status iterator saat ini di subrange.

Jika Anda melanjutkan melewati akhir subrange, iterator diatur ke sentinel di akhir subrange.
Jika Anda melanjutkan melewati awal subrange (menggunakan negatif n), Anda akan mendapatkan pengecualian parameter yang tidak valid jika rentang yang subrange Anda buat dari tidak memiliki elemen di tempat tersebut.

Contoh 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

Dapatkan iterator ke elemen pertama di subrange.

1) constexpr I begin() const requires copyable<I>;
2) [[nodiscard]] constexpr I begin() requires (!std::copyable<I>);

Parameter

Tidak ada.

Nilai hasil

Iterator yang menunjuk pada elemen pertama di subrange. Jika iterator tidak dapat disalin, iterator dikembalikan dengan std::move(). Jika iterator dipindahkan, status iterator yang disimpan tergantung pada implementasi konstruktor pemindahan untuk I.

Gambar vektor dengan elemen 10, 20, dan 30. Elemen pertama berisi 10 dan diberi label begin(). Elemen terakhir berisi 30 dan diberi label 'elemen terakhir'. Kotak imajiner setelah elemen terakhir menunjukkan sentinel dan diberi label end().

empty

Uji apakah subrange kosong.

constexpr bool empty() const;

Parameter

Tidak ada.

Nilai hasil

Mengembalikan true jika subrange tidak memiliki elemen. Jika tidak, kembalikan false.

end

Dapatkan sentinel di akhir subrange

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

Parameter

Tidak ada.

Nilai hasil

Sentinel yang mengikuti elemen terakhir dalam subrange:

Gambar vektor dengan elemen 10, 20, dan 30. Elemen pertama berisi 10 dan diberi label begin(). Elemen terakhir berisi 30 dan diberi label 'elemen terakhir'. Kotak imajiner setelah elemen terakhir menunjukkan sentinel dan diberi label end().

Sentinel dibuat dari sentinel yang disimpan.

next

Membuat salinan ini subrange tetapi dengan iterator tersimpan bergerak maju jarak yang ditentukan.

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) &&;

Parameter

n
Berapa banyak elemen untuk memindahkan iterator ke depan. Default ke 1. Harus positif.

Nilai hasil

Mengembalikan salinan awal subrange di elemen *n*th.

Keterangan

Tidak seperti advance(), next() tidak mengubah lokasi iterator yang disimpan di aslinya subrange. yang dikembalikan subrange memiliki semua elemen yang dimiliki subrange asli, tetapi iterator berada di lokasi yang berbeda.

1) Nilai yang dikembalikan sama dengan:

auto tmp = *this;
tmp.advance(n);
return tmp;

2) Nilai yang dikembalikan sama dengan:

advance(n);
return std::move(*this);

Contoh: 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

Membuat salinan ini subrange, tetapi dengan iterator tersimpan memindahkan kembali jarak yang ditentukan.

[[nodiscard]] constexpr subrange prev(std::iter_difference_t<I> n = 1 ) const
    requires std::bidirectional_iterator<I>;

Parameter

n
Berapa banyak elemen untuk memindahkan iterator kembali. Default ke 1. Harus positif.

Nilai hasil

Mengembalikan salinan subrange tetapi dengan elemen kembali n yang dipindahkan iterator.

Keterangan

Tidak seperti advance(), prev() tidak mengubah lokasi iterator yang disimpan di aslinya subrange.
yang dikembalikan subrange memiliki semua elemen yang dimiliki subrange asli, tetapi iterator hanya di lokasi yang berbeda. Anda dapat menganggap nilai yang dikembalikan sebagai:

auto tmp = *this;
tmp.advance(-n);
return tmp;

Contoh 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

Dapatkan jumlah elemen di subrange.

constexpr size() const
    requires (K == ranges::subrange_kind::sized);

Parameter

Tidak ada.

Nilai hasil

Jumlah elemen dalam subrange.

Jika ukuran tidak disimpan, yang merupakan kasus ketika subrange dibuat dengan K == ranges::subrange_kind::sized yang ditentukan dan std::sized_sentinel_for<S, I> tidak terpenuhi, maka ukuran dikembalikan sebagai jarak antara iterator awal dan akhir.

Mengubah posisi iterator begin , dengan advance, misalnya, mengubah ukuran yang dilaporkan.

Lihat juga

<ranges>
counted
Melihat kelas