Adaptor rentang
Adaptor rentang membuat tampilan (salah satu kelas Tampilan di std::views
namespace layanan) dari rentang. Kami menyarankan agar Anda menggunakan adaptor untuk membuat tampilan alih-alih membuat jenis tampilan secara langsung. Adaptor adalah cara yang dimaksudkan untuk mengakses tampilan. Mereka lebih mudah digunakan, dan dalam beberapa kasus lebih efisien, daripada membuat instans jenis tampilan secara langsung.
Tampilan adalah objek ringan yang mengacu pada elemen dari rentang. Tampilan dapat:
- Hanya terdiri dari elemen tertentu dari rentang.
- Mewakili transformasi elemen dari rentang.
- Jadilah kebalikan dari, atau hanya elemen pertama
n
, rentang. - Jadilah kombinasi dari hal-hal sebelumnya.
Tampilan murah, O(1)
, untuk menyalin, menetapkan, dan menghancurkan - tidak peduli berapa banyak elemen yang terlibat. Pertimbangkan contoh berikut:
// requires /std:c++20 or later
#include <ranges>
#include <vector>
#include <iostream>
int main()
{
std::vector<int> input = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto divisible_by_three = [](const int n) {return n % 3 == 0;};
auto square = [](const int n) {return n * n;};
auto x = input | std::views::filter(divisible_by_three)
| std::views::transform(square);
for (int i : x)
{
std::cout << i << ' ';
}
}
0 9 36 81
Adaptor rentang pertama, filter
, menyediakan tampilan yang berisi elemen dari input
yang dapat dibagi tiga. Adaptor rentang lainnya, transform
, mengambil tampilan yang berisi elemen yang dapat dibagi tiga dan memberikan tampilan kuadrat dari elemen-elemen tersebut.
Saat adaptor rentang menghasilkan tampilan, adaptor rentang tidak dikenakan biaya untuk mengubah setiap elemen dalam rentang untuk menghasilkan tampilan tersebut. Biaya untuk memproses elemen dalam tampilan hanya dibayar saat Anda mengakses elemen tersebut.
Membuat tampilan adalah persiapan untuk melakukan pekerjaan di masa mendatang. Dalam contoh sebelumnya, membuat tampilan tidak mengakibatkan menemukan semua elemen yang dapat dibagi dengan tiga atau memadai elemen-elemen tersebut. Pekerjaan hanya terjadi saat Anda mengakses elemen dalam tampilan.
Elemen tampilan biasanya merupakan elemen aktual dari rentang yang digunakan untuk membuat tampilan. Tampilan biasanya tidak memiliki elemen; itu hanya mengacu pada mereka, dengan pengecualian owning_view
. Mengubah elemen mengubah elemen tersebut dalam rentang tempat tampilan dibuat. Contoh berikut menunjukkan perilaku ini:
#include <algorithm>
#include <iostream>
#include <ranges>
int main()
{
int input[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto even = [](const int n) { return n % 2 == 0; };
auto x = input | std::views::filter(even); // create a view of the even elements from input
for (int &i : x)
{
std::cout << i << ' '; // 0 2 4 6 8 10
}
std::cout << '\n';
std::ranges::fill(x, 42); // changes the evens from input[] to 42
for (int &i : input) // demonstrates that the even elements in the range are modified
{
std::cout << i << ' '; // // 42 1 42 3 42 5 42 7 42 9 42
}
}
Adaptor rentang hadir dalam banyak bentuk. Misalnya, ada adaptor rentang yang memungkinkan Anda menghasilkan tampilan dengan:
- Memfilter rentang lain berdasarkan predikat (
filter
). - Mengubah elemen dalam rentang (
transform
). - Memisahkan rentang (
split
).
Adaptor rentang dapat dirantai bersama -sama (terdiri). Di situlah daya dan fleksibilitas rentang paling jelas. Menyusun adaptor rentang memungkinkan Anda mengatasi masalah inti dengan algoritma Standard Template Library (STL) sebelumnya, yaitu tidak mudah untuk dirantai bersama.
Adaptor rentang berikut tersedia di std::views
namespace layanan. Namespace std::views
layanan adalah alias kenyamanan untuk std::ranges::views
.
Adaptor rentang | Deskripsi |
---|---|
all C++20 |
Buat tampilan yang mengacu pada rentang dan elemennya. |
common C++20 |
Buat tampilan yang memiliki jenis iterator dan sentinel yang sama dari rentang yang tidak. |
counted C++20 |
Buat tampilan elemen n pertama dari rentang, dimulai dari lokasi yang ditentukan. |
drop C++20 |
Buat tampilan dari tampilan lain, melewati jumlah elemen yang ditentukan dari depan. |
drop_while C++20 |
Buat tampilan yang berisi elemen rentang yang tersisa setelah elemen terkemuka yang cocok dengan kondisi yang ditentukan dihilangkan. |
elements C++20 |
Buat tampilan indeks yang dipilih ke dalam setiap nilai seperti tuple dalam rentang. |
empty C++20 |
Buat tampilan yang tidak memiliki elemen. |
filter C++20 |
Buat tampilan yang berisi elemen rentang yang cocok dengan kondisi yang ditentukan. |
iota C++20 |
Buat tampilan yang berisi urutan peningkatan nilai. |
istream C++20 |
Buat tampilan di atas elemen aliran. |
join C++20 |
Buat tampilan yang menggabungkan semua elemen dari beberapa rentang ke dalam satu tampilan. |
keys C++20 |
Buat tampilan indeks pertama ke dalam setiap nilai seperti tuple dalam koleksi. |
lazy_split C++20 |
Pisahkan tampilan menjadi subrang berdasarkan pemisah. |
reverse C++20 |
Buat tampilan elemen rentang dalam urutan terbalik. |
single C++20 |
Buat tampilan yang berisi satu elemen. |
split C++20 |
Pisahkan tampilan menjadi subrang berdasarkan pemisah. |
take C++20 |
Buat tampilan elemen n pertama dari tampilan lain. |
take_while C++20 |
Buat tampilan yang berisi elemen utama rentang yang cocok dengan kondisi yang ditentukan. |
transform C++20 |
Buat tampilan elemen yang diubah dari tampilan lain. |
values C++20 |
Buat tampilan indeks kedua ke dalam setiap nilai seperti tuple dalam koleksi. |
Dalam tabel sebelumnya, adaptor rentang biasanya dijelaskan sebagai mengambil rentang dan menghasilkan tampilan. Tepatnya, adaptor rentang memiliki argumen rentang yang menerima salah satu hal berikut:
- Model
cv-unqualified
view
jenis , dan argumen adalah rvalue atau dapat disalin. - Ketika Anda meneruskan argumen sebagai lvalue, argumen harus memodelkan
range
dan hidup selama tampilan. - Ketika Anda meneruskan argumen sebagai rvalue, seperti saat memanggil , argumen harus
range
memodelkanowning_view
danmovable
.
Fungsi adaptor rentang biasanya merupakan objek fungsi, yang terlihat seperti panggilan fungsi dan memberlakukan batasan pada jenis yang dapat diteruskan.
Anda dapat meneruskan adaptor rentang dan hasil operasi pipa (|
) ke kode yang mengharapkan objek fungsi. Dalam contoh berikut, tampilan yang split
dibuat adaptor rentang diteruskan ke transform
adaptor rentang seolah-olah oleh panggilan fungsi, karena transform
adaptor rentang adalah objek fungsi.
std::map<int, string> x = {{0, "Hello, world"}, {42, "Goodbye, world"}};
auto y = x | views::values | views::transform(views::split(' '));
// y is a range whose elements are ranges of whitespace-delimited strings from each value in x:
// {{"Hello", "world"}, {"Goodbye", "world"}}
all
Buat tampilan semua elemen dalam rentang.
template <ranges::viewable_range R>
constexpr ranges::view auto all(R&& rg) const noexcept;
Parameter
R
Jenis rentang yang mendasar.
rg
Rentang untuk membuat tampilan dari.
Nilai hasil
- Jika
rg
sudah menjadi tampilan, salinanrg
. - Jika
rg
adalah lvalue non-tampilan,ref_view
yang mengacu padarg
. (Masa pakai tampilan terikat dengan masarg
pakai .) - Jika
rg
adalah rvalue non-tampilan seperti objek sementara, atau merupakan hasil dari meneruskan rentang kestd::move
, sebuahowning_view
.
Gunakan std::views::all_t<decltype((rg))>
untuk mendapatkan jenis tampilan yang dikembalikan.
Keterangan
Adaptor rentang ini adalah cara terbaik untuk mengonversi rentang menjadi tampilan. Salah satu alasan untuk membuat tampilan dari rentang adalah untuk meneruskannya berdasarkan nilai dengan biaya rendah, jika melewati rentang berdasarkan nilai bisa mahal.
Mendapatkan tampilan untuk rentang adalah alternatif yang berguna untuk melewati rentang kelas berat berdasarkan nilai karena tampilan murah untuk dibuat, disalin, dan dihancurkan. Pengecualian yang mungkin adalah owning_view
, yang merupakan tampilan yang memiliki rentang yang mendasar.
Secara umum, skenario terburuk untuk menghancurkan tampilan memiliki O(N)
kompleksitas untuk jumlah elemen dalam rentang. Bahkan jika Anda menghancurkan K
salinan tampilan dengan N
elemen, kompleksitas total masih O(N)
karena rentang yang mendasar dihancurkan hanya sekali.
Contoh: all
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v = {1,2,3,4,5,6,7,8,9,10};
auto myRefView = std::views::all(v); // create a ref_view of the vector
std::cout << myRefView.size() << '\n'; // 10
auto myOwningView = std::views::all(std::move(v)); // create an owning_view from a moved vector
std::cout << myRefView.size() << '\n'; // outputs 0 because myOwningView now owns the elements
std::cout << v.size() << '\n'; // outputs 0 because myOwningView now owns the elements
std::cout << myOwningView.size(); // 10
}
10
0
0
10
common
Buat tampilan yang memiliki iterator mulai dan jenis sentinel yang sama dari rentang yang mungkin tidak.
template <ranges::viewable_range R>
constexpr ranges::view auto common(R&& rg) const noexcept;
Parameter
R
Jenis rentang yang mendasar.
rg
Rentang untuk membuat tampilan dari.
Nilai hasil
views::all(rg)
jikarg
adalah rentang dengan iterator dan jenis sentinel yang sama.common_view(views::all(rg))
jikarg
memiliki jenis iterator dan sentinel yang berbeda.
Keterangan
Ketika API memerlukan iterator awal dan sentinel akhir untuk memiliki jenis yang sama, dan tampilan yang Anda gunakan tidak memenuhi persyaratan tersebut (atau Anda tidak tahu apakah itu terjadi), gunakan adaptor rentang ini untuk membuat common_view
. Ini menjamin bahwa jenis iterator mulai dan jenis sentinel akhir sama.
Contoh: common
// requires /std:c++20 or higher
#include <ranges>
#include <iostream>
#include <numeric>
#include <list>
int main()
{
std::list<int> lst{1, 2, 3, 4, 5, 6, 7, 8, 9};
auto firstFive = std::views::take(lst, 5);
// firstFive.begin(), firstFive.end() have different types: counted_iterator versus default_sentinel
// auto r = std::accumulate(firstFive.begin(), firstFive.end(), 0); // Error: accumulate() requires firstFive.begin() and firstFive.end() types to be the same.
auto common = std::views::common(firstFive); // create a common_view that has the same begin/end iterator types
std::cout << std::accumulate(common.begin(), common.end(), 0); // Now you can call the API because the iterator types are the same. Outputs 15 (1+2+3+4+5)
}
15
counted
Buat tampilan elemen pertama count
rentang, dimulai dari lokasi yang ditentukan.
template<class Iterator>
constexpr auto counted(Iterator&& it, iter_difference_t<Iterator> count);
Parameter
DifferenceType
Jenis hitungan.
Iterator
Jenis iterator.
count
Jumlah elemen yang akan disertakan dalam tampilan. Harus non-negatif.
- Jika
count == 0
, kosongspan
dikembalikan. - Jika
count
lebih besar dari jumlah elemen dalam rentang, perilaku tidak ditentukan.
it
Iterator ke elemen dalam rentang untuk memulai. Elemen yang dituju iterator disertakan dalam tampilan yang dibuat.
Nilai hasil
span
dikembalikan jika it
adalah contiguous_iterator
untuk array, vektor, dan kontainer lain yang menyimpan elemennya secara berdekatan. Jika tidak, akan subrange
dikembalikan.
Keterangan
Elemen yang disertakan adalah [it, count)
.
Setelah tampilan dibuat, jumlah elemen dalam tampilan tetap sama, bahkan jika rentang yang dibuat dari perubahan. Namun, jika rentang yang mendasar berubah, mengakses elemen dari tampilan dapat mengakibatkan perilaku yang tidak ditentukan.
Contoh: counted
// requires /std:c++20 or later
#include <algorithm>
#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
drop
Buat tampilan yang mengecualikan elemen n pertama dari rentang.
1) template<ranges::viewable_range R>
constexpr ranges::view auto drop(R&& rg, ranges::range_difference_t<R> count);
2) template<class DifferenceType>
constexpr /* range closure object */ drop(DifferenceType&& count);
Parameter
DifferenceType
Jenis yang menjelaskan jumlah elemen yang akan dilewati.
count
Jumlah elemen yang akan dijatuhkan dari depan rg
. Harus non-negatif.
- Jika
count == 0
, semua elemen dirg
dikembalikan. - Jika
count
lebih besar dari jumlah elemen dalamrg
, tampilan kosong dikembalikan.
R
Jenis rentang.
rg
Rentang yang digunakan untuk membuat tampilan.
Nilai hasil
Tampilan rentang yang mendasar, dengan jumlah elemen yang ditentukan dihilangkan dari depan.
Jika Anda menentukan lebih banyak elemen untuk dihilangkan daripada yang ada dalam rentang yang mendasar, maka empty_view
akan dikembalikan.
Tampilan yang dikembalikan biasanya, tetapi tidak selalu, spesialisasi dari drop_view
. Yaitu:
- Jika
V
adalah spesialisasi dariempty_view
, atau adalah spesialisasi darispan
, ,basic_string_view
iota_view
, atausubrange
yang keduanyarandom_access_range
dansized_range
, hasilnya adalah spesialisasi dariV
. - Jika tidak, hasilnya adalah
drop_view
.
Keterangan
Setelah dibuat, jumlah elemen dalam tampilan tetap sama meskipun tampilan dibuat dari perubahan. Namun, jika tampilan yang mendasar berubah, mengakses elemen dalam tampilan yang dikembalikan dapat mengakibatkan perilaku yang tidak ditentukan.
drop
adalah kebalikan dari take
.
Kode yang ditampilkan sebelumnya sebagai "2)" dapat digunakan dengan sintaks pipa: collection | drop(5)
. Atau dapat digunakan dengan sintaks panggilan fungsi: drop(collection, 5)
atau drop(5)(collection)
.
Contoh: drop
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v{1, 2, 3, 4, 5};
auto newView = std::views::drop(v, 3);
for (auto e : newView) // 4 5
{
std::cout << e << ' ';
}
std::cout << '\n';
auto numbers = std::views::iota(0) | std::views::take(10); // build a view of 10 integers
auto latterHalf = numbers | std::views::drop(5);
for (auto i : latterHalf)
{
std::cout << i << ' '; // 5 6 7 8 9
}
}
4 5
5 6 7 8 9
drop_while
Buat tampilan yang berisi elemen rentang yang tersisa setelah elemen terkemuka yang cocok dengan kondisi yang ditentukan dihilangkan.
1) template<ranges::viewable_range R, class P>
constexpr ranges::view auto drop_while(R&& rg, P&& predicate);
2) template<class P>
constexpr /*range adaptor closure*/ drop_while(P&& predicate);
Parameter
R
Jenis rentang.
predicate
Kondisi yang menentukan elemen terkemuka mana yang akan dihilangkan dari rentang.
rg
Rentang yang mendasar untuk membuat tampilan.
Nilai hasil
drop_while_view
yang terdiri dari elemen yang tetap ada ketika elemen terkemuka yang cocok dengan predikat dihilangkan.
Keterangan
Berhenti menghilangkan elemen segera rg
setelah predikat mengembalikan false
.
drop_while
adalah kebalikan dari take_while
.
Kode yang ditampilkan sebelumnya sebagai "2)" dapat digunakan dengan sintaks pipa: collection | drop_while(predicate)
. Atau dapat digunakan dengan sintaks panggilan fungsi: drop_while(collection, predicate)
atau drop_while(predicate)(collection)
.
Contoh: drop_while
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
void print(auto&& v)
{
for (auto&& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
std::vector<int> v{ 0, 1, 2, 3, -4, 5, 6 };
auto myView = std::views::drop_while(
v,
[](int i) {return i >= 0; });
print(myView); // -4 5 6
auto myView2 = v | std::views::drop_while(
[](int i) {return i < 5; });
print(myView2); // 5 6
}
-4 5 6
5 6
elements
elements_view
Buat , yang merupakan tampilan indeks yang dipilih ke dalam setiap nilai seperti tuple dalam rentang. Misalnya, mengingat rentang std::tuple<string, int>
nilai, buat elements_view
salah satu dari semua string
elemen dari setiap tuple.
template<ranges::viewable_range R, size_t N>
constexpr ranges::view auto elements<N>(R&& rg);
Parameter
N
Indeks elemen yang akan dipilih dari setiap nilai seperti tuple untuk disertakan dalam tampilan.
R
Jenis rentang yang mendasar.
rg
Rentang nilai seperti tuple untuk membuat tampilan.
Nilai hasil
Yang elements_view
terdiri dari indeks yang dipilih ke dalam setiap nilai seperti tuple dalam koleksi.
Contoh: elements
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <map>
#include <string>
int main()
{
std::map<std::string, int> cpp_standards
{
{"C++98", 1998},
{"C++03", 2003},
{"C++11", 2011},
{"C++14", 2014},
{"C++17", 2017},
{"C++20", 2020}
};
// Create an elements_view of all the string elements from each tuple
for (int const year : std::views::elements<1>(cpp_standards))
{
std::cout << year << ' '; // 2003 2011 2014 2017 1998 2020
}
std::cout << '\n';
// Another way, using |: create an elements_view of all the int elements from each tuple
for (auto&& name : cpp_standards | std::views::elements<0>)
{
std::cout << name << ' '; // C++03 C++11 C++14 C++17 C++98 c++20
}
}
2003 2011 2014 2017 1998 2020
C++03 C++11 C++14 C++17 C++98 c++20
empty
empty_view
Buat , yang merupakan tampilan yang tidak memiliki elemen.
template<class T>
inline constexpr empty_view<T> empty{};
Parameter
T
Jenis elemen dalam tampilan. Tampilan membutuhkan jenis elemen, meskipun tidak ada elemen.
Nilai hasil
Sebuah empty_view
.
Keterangan
empty_view
Dapat berguna saat Anda memanggil kode yang memerlukan tampilan tetapi tidak perlu memproses salah satu elemennya.
Contoh: empty
// requires /std:c++20 or higher
#include <ranges>
#include <iostream>
int main()
{
auto anEmptyView = std::views::empty<int>;
bool isNotEmpty = (bool)anEmptyView;
std::cout << boolalpha << isNotEmpty << "\n"; // false
}
false
filter
Buat tampilan yang berisi elemen rentang yang cocok dengan kondisi yang ditentukan.
1) template<ranges::viewable_range R, class P>
requires {filter_view(forward<R>(rg), forward<P>(predicate));}
constexpr ranges::view auto filter(R&& rg, P&& predicate);
2) template<class P>
constexpr /*range adaptor closure*/ filter(P&& predicate);
Parameter
P
Jenis predikat.
predicate
Kondisi yang menentukan elemen mana yang akan disimpan dalam rentang.
R
Jenis rentang yang mendasar.
rg
Rentang untuk membuat tampilan dari.
Nilai hasil
filter_view
yang berisi elemen rentang yang cocok dengan predikat.
Keterangan
Demi efisiensi, ketika Anda menggunakan filter
dan transform
bersama dengan pipa |
, lakukan yang filter
pertama sehingga Anda transform
hanya elemen yang ingin Anda simpan.
Kode yang ditampilkan sebelumnya sebagai "2)" dapat digunakan dengan sintaks pipa: collection | filter(predicate)
. Atau dapat digunakan dengan sintaks panggilan fungsi: filter(collection, predicate)
atau filter(predicate)(collection)
.
Contoh: filter
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
void print(auto&& v)
{
for (auto&& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
std::vector<int> v{0, 1, 2, 3, -4, 5, 6};
auto myView = std::views::filter(v, [](int i) {return i < 5; });
print(myView); // 0 1 2 3 -4
auto myView2 = v | std::views::filter([](int i) {return i < 5; }); // pipe syntax
print(myView2); // 0 1 2 3 -4
}
0 1 2 3 -4
0 1 2 3 -4
iota
Buat tampilan yang berisi urutan peningkatan nilai. Urutan dapat dibatasi atau tidak.
template<class V>
constexpr ranges::view auto iota(V&& startValue); // create an unbounded sequence of incrementing values
template<class V, class E>
constexpr ranges::view auto iota(V&& startValue, E&& endValue); // create a bounded sequence of incrementing values
Parameter
E
Jenis nilai akhir.
S
Jenis nilai awal.
startValue
Nilai pertama dalam urutan.
endValue
Nilai ini melewati nilai terakhir yang akan berada dalam urutan. Misalnya, std::views::iota(0, 5)
menghasilkan tampilan yang memiliki nilai 0,1,2,3,4
.
Nilai hasil
Urutan iota_view
peningkatan nilai.
Keterangan
Untuk urutan yang tidak terbatas, perilaku tidak ditentukan setelah nilai maksimum jenis datanya tercapai.
Contoh: iota
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
void print(auto&& v)
{
for (auto&& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
// create an iota view with its range adaptor (preferred)
print(std::views::iota(0, 5)); // outputs 0 1 2 3 4
// create an iota_view class directly
std::ranges::iota_view letters{'a', 'f'};
print(letters); // a b c d e
}
0 1 2 3 4
a b c d e
istream
Buat tampilan di atas elemen aliran.
template <class Val>
views::istream<Val>(str);
Parameter
str
Objek streaming. Jenisnya berasal dari spesialisasi std::basic_istream
.
Val
Jenis elemen yang akan diekstrak dari aliran.
Nilai hasil
Adaptor rentang ini setara dengan ranges::basic_istream_view<Val, typename U::char_type, typename U::traits_type>(str)
, di mana U
adalah jenis str
.
Contoh: istream
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <sstream>
#include <vector>
int main()
{
std::istringstream doubles{"1.1 2.2 3.3 4.4 5.5"};
for (const auto& elem : std::views::istream<double>(doubles))
{
std::cout << elem << ' '; // 1.1 2.2 3.3 4.4 5.5
}
}
1.1 2.2 3.3 4.4 5.5
join
Buat tampilan yang menggabungkan semua elemen dari beberapa rentang ke dalam satu tampilan.
1) template <ranges::viewable_range R>
[[nodiscard]] constexpr ranges::view auto join(R&& rg) const noexcept;
2) inline constexpr /*range adaptor closure*/ join();
Parameter
R
Jenis rentang yang mendasar.
rg
Rentang untuk membuat tampilan dari.
Nilai hasil
yang join_view
berisi elemen semua rentang dalam rentang yang mendasar.
Contoh: join
#include <iostream>
#include <vector>
#include <ranges>
#include <string>
int main()
{
// a range of two ranges
std::vector<std::string> rangeOfRanges[2]{{"C++20", "contains:"}, {"ranges", "modules", "concepts & more."}};
for (const auto& elem : std::views::join(rangeOfRanges))
{
std::cout << elem << ' ';
}
}
C++20 contains: ranges modules concepts & more.
Keterangan
Kode yang ditampilkan sebelumnya sebagai "2)" dapat digunakan dengan sintaks pipa: collection | join
. Atau dapat digunakan dengan sintaks panggilan fungsi: join(collection)
.
keys
Buat keys_view
indeks pertama ke dalam setiap nilai seperti tuple dalam koleksi. Ini berguna untuk mengekstrak kunci dari kontainer asosiatif. Misalnya, diberikan berbagai std::tuple<string, int>
, buat tampilan yang terdiri dari semua string
elemen dari setiap tuple.
template <ranges::viewable_range R>
constexpr auto keys(R&& rg);
Parameter
R
Jenis rentang yang mendasar.
Nilai hasil
keys_view
yang terdiri dari indeks pertama ke dalam setiap nilai seperti tuple dalam rentang.
Contoh: keys
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <map>
#include <string>
#include <vector>
int main()
{
// ========== extract keys from a map
std::map<std::string, int> cpp_standards
{
{"C++98", 1998},
{"C++03", 2003},
{"C++11", 2011},
{"C++14", 2014},
{"C++17", 2017},
{"C++20", 2020}
};
// Extract all of the keys from the map
for (std::string standards : std::views::keys(cpp_standards))
{
std::cout << standards << ' '; // C++03 C++11 C++14 C++17 C++98 C++20
}
std::cout << '\n';
// ========== Extract keys from a pair
std::vector<std::pair<std::string, int>> windows
{
{"Windows 1.0", 1985},
{"Windows 2.0", 1987},
{"Windows 3.0", 1990},
{"Windows 3.1", 1992},
{"Windows NT 3.1", 1993},
{"Windows 95", 1995},
{"Windows NT 4.0", 1996},
{"Windows 95", 1995},
{"Windows 98", 1998},
{"Windows 1.0", 1985},
{"Windows 2000", 2000}
};
// Another way to call the range adaptor is by using '|'
for (std::string version : windows | std::views::keys)
{
std::cout << version << ' '; // Windows 1.0 Windows 2.0 Windows 3.0 ...
}
}
C++03 C++11 C++14 C++17 C++98 C++20
Windows 1.0 Windows 2.0 Windows 3.0 Windows 3.1 Windows NT 3.1 Windows 95 Windows NT 4.0 Windows 95 Windows 98 Windows 1.0 Windows 2000
lazy_split
Pisahkan rentang menjadi subrang berdasarkan pemisah. Pemisah dapat menjadi elemen tunggal atau tampilan elemen.
1) template<viewable_range R, class Pattern>
constexpr view auto lazy_split(R&& rg, Pattern&& delimiter);
2) template<class Pattern>
constexpr /*range adaptor closure*/ lazy_split(Pattern&& delimiter);
Parameter
delimiter
Nilai tunggal, atau urutan nilai yang menentukan tempat untuk memisahkan rentang.
Pattern
Jenis pemisah.
R
Jenis rentang yang akan dipisahkan.
rg
Rentang untuk dipisahkan.
Nilai hasil
lazy_split_view
yang berisi satu atau beberapa subranges dan merupakan hasil dari pemisahan rentang asli pada delimiter
.
Keterangan
Pemisah bukan bagian dari hasil. Misalnya, jika Anda membagi rentang 1,2,3
pada nilai 2
, Anda mendapatkan dua subrang: 1
dan 3
.
Adaptor terkait adalah split
. Perbedaan utama antara [split_view](split-view-class.md) and
lazy_split_view' adalah:
Tampilkan | Dapat memisahkan const rentang |
Perulang rentang |
---|---|---|
split_view |
no | forward_range Mendukung atau lebih tinggi |
lazy_split_view |
yes | input_range atau lebih tinggi |
Lebih suka split_view
karena lebih efisien, kecuali Anda harus membagi rentang yaitu const
.
Kode yang ditampilkan sebelumnya sebagai "2)" dapat digunakan dengan sintaks pipa: collection | lazy_split(delimiter)
. Atau dapat digunakan dengan sintaks panggilan fungsi: lazy_split(collection, delimiter)
atau lazy_split(delimiter)(collection)
.
Contoh: lazy_split
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> rg{1, 2, 3, 1, 2, 3, 4, 5, 6};
// split on a single element
for (const auto& sub : rg | std::views::split(3))
{
// outputs:
// 1 2
// 1 2
// 4 5 6
for (const auto& elem : sub)
{
std::cout << elem << ' ';
}
std::cout << '\n';
}
// split on a sequence of elements
int delimiters[] = {2, 3};
for (const auto& subrange : std::views::split(rg, delimiters))
{
// outputs 1 1 4 5 6
for (auto& i : subrange)
{
std::cout << i << " ";
}
}
}
1 2
1 2
4 5 6
1 1 4 5 6
reverse
Buat tampilan elemen rentang dalam urutan terbalik.
1) template<viewable_range R>
constexpr ranges::view auto reverse(R&& rg);
2) inline constexpr /*range adaptor closure*/ reverse();
Parameter
R
Jenis rentang yang mendasar untuk membalikkan.
rg
Rentang untuk membalikkan.
Nilai hasil
Tampilan yang menyajikan elemen rentang yang mendasar dalam urutan terbalik. Tampilan yang dikembalikan biasanya, tetapi tidak selalu, spesialisasi dari reverse_view
. Yaitu:
- Jika
V
merupakan spesialisasi darireverse_view
, hasilnya adalah tampilan mendasar argumen. Double-reverse adalah no-op (tanpa operasi). - Jika
V
memiliki formulirsubrange<reverse_iterator<I>, reverse_iterator<I>>
, hasilnya adalahsubrange
dari iterator yang dibungkus. Double-reverse adalah no-op. - Jika tidak, hasilnya adalah
reverse_view
.
Keterangan
Kode yang ditampilkan sebelumnya sebagai "2)" dapat digunakan dengan sintaks pipa: collection | reverse
. Atau dapat digunakan dengan sintaks panggilan fungsi: reverse(collection)
.
Contoh: reverse
// 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 };
auto rv = v | std::views::reverse; // using the pipe syntax
for (auto &&e : rv) // outputs 6 5 -4 3 2 1 0
{
std::cout << e << ' ';
}
std::cout << '\n';
// using the range adaptor without using the pipe syntax
auto rv2 = std::views::reverse(v);
for (auto &&e : rv2) // outputs 6 5 -4 3 2 1 0
{
std::cout << e << ' ';
}
}
6 5 -4 3 2 1 0
6 5 -4 3 2 1 0
single
Buat single_view
, yang merupakan tampilan yang berisi satu elemen.
template<class T>
constexpr ranges::view auto single(T&& t);
Parameter
T
Jenis elemen dalam tampilan.
t
Nilai elemen yang akan disimpan dalam tampilan.
Nilai hasil
Yang single_view
berisi t
.
Keterangan
Tampilan ini berguna untuk tujuan pengujian, untuk kode panggilan yang perlu disediakan dengan tampilan yang memiliki setidaknya satu elemen di dalamnya.
Contoh: single
// requires /std:c++20 or higher
#include <ranges>
#include <string>
#include <tuple>
#include <iostream>
int main()
{
auto sv = std::views::single(7);
std::cout << sv.front() << " " << *sv.data() << "\n"; // 7 7
auto sv2 = std::views::single(<std::tuple<double, std::string>{6502, "8-bit"});
std::cout << std::get<0>(sv2[0]) << " " << std::get<1>(sv2[0]) << "\n"; // 6502 8-bit
}
7 7
6502 8-bit
split
Pisahkan tampilan menjadi subrang berdasarkan pemisah. Pemisah dapat menjadi elemen tunggal atau urutan elemen.
1) template<viewable_range R, class Pattern>
constexpr view auto split(R&& rg, Pattern&& delimiter);
2) template<class Pattern>
constexpr /*range adaptor closure*/ split(Pattern&& delimiter);
Parameter
delimiter
Nilai tunggal, atau urutan nilai yang menentukan tempat untuk memisahkan rentang.
Pattern
Jenis pemisah.
R
Jenis rentang yang mendasar untuk dipisahkan.
rg
Rentang untuk dipisahkan.
Nilai hasil
Yang split_view
berisi satu atau beberapa subrang.
Keterangan
Pemisah bukan bagian dari hasil. Misalnya, jika Anda membagi rentang 1,2,3
pada nilai 2
, Anda mendapatkan dua subrang: 1
dan 3
.
Adaptor terkait adalah lazy_split
. Perbedaan utama antara split_view
dan lazy_split_view
adalah:
Tampilkan | Dapat memisahkan const rentang |
Jenis rentang |
---|---|---|
split_view |
no | forward_range Mendukung atau lebih tinggi |
lazy_split_view |
yes | input_range Mendukung atau lebih tinggi |
Lebih suka split_view
karena lebih efisien, kecuali Anda harus membagi rentang yaitu const
.
Kode yang ditampilkan sebelumnya sebagai "2)" dapat digunakan dengan sintaks pipa: collection | split(delimiter)
. Atau dapat digunakan dengan sintaks panggilan fungsi: split(collection, 5)
atau split(5)(collection)
.
Contoh: split
// requires /std:c++20 or later
#include <ranges>
#include <vector>
#include <iostream>
int main()
{
std::vector<int> rg{ 1, 2, 3, 1, 2, 3, 4, 5, 6 };
// split on a single element, 3
for (const auto& sub : rg | std::views::split(3))
{
// This prints out:
// 1,2
// 4,5,6
for (const auto& elem : sub)
{
std::cout << elem << ' ';
}
std::cout << '\n';
}
// split on a sequence of elements, 2,3
int delimiters[] = {2, 3};
for (const auto& subrange : std::views::split(rg, delimiters))
{
// outputs 1 1 4 5 6
for (auto& i : subrange)
{
std::cout << i << " ";
}
}
}
1 2
1 2
4 5 6
1 1 4 5 6
take
Buat tampilan yang berisi jumlah elemen yang ditentukan yang diambil dari depan rentang.
1) template<ranges::viewable_range R>
constexpr ranges::view auto take(R&& rg, ranges::range_difference_type<R> count);
2) template<class DifferenceType>
constexpr /*range adaptor closure*/ take(DifferenceType&& count);
Parameter
R
Jenis rentang yang mendasar.
rg
Rentang untuk membuat tampilan dari.
count
Jumlah elemen yang akan diambil dari depan rg
.
Nilai hasil
Tampilan yang dikembalikan biasanya, tetapi tidak selalu, spesialisasi dari take_view
. Khususnya:
- Jika
V
adalah spesialisasi dariempty_view
, atau adalah spesialisasi darispan
, ,basic_string_view
iota_view
, atausubrange
yang keduanyarandom_access_range
dansized_range
, hasilnya adalah spesialisasi dariV
. - Jika tidak, hasilnya adalah
take_view
.
Keterangan
Jika Anda menentukan lebih banyak elemen yang akan diambil daripada yang ada di rg
, semua elemen diambil.
take
adalah kebalikan dari drop
.
Kode yang ditampilkan sebelumnya sebagai "2)" dapat digunakan dengan sintaks pipa: collection | take(5)
. Atau dapat digunakan dengan sintaks panggilan fungsi: take(5, collection)
atau take(5)(collection)
.
Contoh: take
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::string s{ "abcdefg" };
auto myView = std::views::take(s, 3);
for (auto c : myView)
{
std::cout << c << ' '; // a b c
}
std::cout << std::endl;
for (auto c : s | std::views::take(3)) // pipe syntax
{
std::cout << c << ' '; // a b c
}
}
a b c
a b c
take_while
Buat tampilan yang berisi elemen utama rentang yang cocok dengan kondisi yang ditentukan.
1) template<ranges::viewable_range R, class P>
constexpr ranges::view auto take_while(R&& rg, P&& predicate);
2) template<class P>
constexpr /*range adaptor closure*/ take_while(P&& predicate);
Parameter
P
Jenis predikat.
predicate
Kondisi yang menentukan elemen terkemuka mana yang akan disalin dari rentang.
R
Jenis rentang yang mendasar.
rg
Rentang untuk membuat tampilan dari.
Nilai hasil
take_while_view
yang terdiri dari elemen pertama count
yang memenuhi kriteria yang ditentukan dalam rentang.
Keterangan
Berhenti mengambil elemen dari rg
setelah predikat kembali false
atau rentang kehabisan elemen.
take_while
adalah kebalikan dari drop_while
.
Kode yang ditampilkan sebelumnya sebagai "2)" dapat digunakan dengan sintaks pipa: collection | take_while(pred)
. Atau dapat digunakan dengan sintaks panggilan fungsi: take_while(collection, pred)
atau take_while(pred)(collection)
.
Contoh: take_while
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
void print(auto&& v)
{
for (auto&& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
std::vector<int> v{ 0, 1, 2, 3, -4, 5, 6 };
auto myView = std::views::take_while(
v, [](int i) {return i >= 0; });
print(myView); // 0 1 2 3
print(v | std::views::take_while( // 0 1 2 3 -4
[](int i) {return i < 5; })); // pipe syntax
}
0 1 2 3
0 1 2 3 -4
transform
Buat tampilan elemen, yang masing-masing merupakan transformasi elemen dalam rentang yang ditentukan.
1) template<viewable_range R, class F>
constexpr ranges::view auto transform(R&& rg, F&& fun);
2) template<class F>
constexpr /*range adaptor closure*/ transform(F&& fun);
Parameter
F
Jenis objek fungsi untuk mengubah elemen.
R
Jenis rentang yang mendasar.
fun
Fungsi yang mengubah elemen.
rg
Rentang untuk membuat tampilan dari.
Nilai hasil
transform_view
yang berisi elemen yang diubah dari rg
.
Keterangan
Demi efisiensi, ketika Anda menyusun filter
dan transform
, lakukan yang filter
pertama sehingga Anda transform
hanya elemen yang ingin Anda simpan.
Kode yang ditampilkan sebelumnya sebagai "2)" dapat digunakan dengan sintaks pipa: collection | transform(fun)
. Atau dapat digunakan dengan sintaks panggilan fungsi: transform(collection, fun)
atau transform(fun)(collection)
.
Contoh: transform
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <vector>
void print(auto&& v)
{
for (auto&& x : v)
{
std::cout << x << ' ';
}
std::cout << '\n';
}
int main()
{
std::vector<int> v{0, 1, 2, 3, -4, 5, 6};
auto myView = std::views::transform(v, [](int i) {return i * 2; });
print(myView); // 0 2 4 6 -8 10 12
print(v | std::views::transform( // 0 2 4 6 -8 10 12
[](int i) {return i * 2; })); // pipe syntax
}
0 2 4 6 -8 10 12
0 2 4 6 -8 10 12
values
values_view
Buat yang terdiri dari indeks kedua ke dalam setiap nilai seperti tuple dalam koleksi. Ini berguna untuk membuat tampilan nilai dalam kontainer asosiatif. Misalnya, mengingat rentang std::tuple<string, int>
nilai, buat tampilan yang terdiri dari semua int
elemen dari setiap tuple.
template <range::viewable_range R>
constexpr ranges::view auto values(R&& rg);
Parameter
R
Jenis rentang yang mendasar.
rg
Rentang nilai seperti tuple yang mendasar.
Nilai hasil
Dibangun values_view
dari indeks kedua ke dalam setiap nilai seperti tuple dalam rentang.
Contoh: values
// requires /std:c++20 or later
#include <ranges>
#include <iostream>
#include <map>
#include <string>
#include <vector>
int main()
{
// ========== working with a map
std::map<std::string, int> cpp_standards
{
{"C++98", 1998},
{"C++03", 2003},
{"C++11", 2011},
{"C++14", 2014},
{"C++17", 2017},
{"C++20", 2020}
};
// Extract all of the years from the map
for (int years : std::views::values(cpp_standards))
{
std::cout << years << ' '; // 2003 2011 2014 2017 1998 2020
}
std::cout << '\n';
// ========== working with pairs
std::vector<std::pair<std::string, int>> windows
{
{"Windows 1.0", 1985},
{"Windows 2.0", 1987},
{"Windows 3.0", 1990},
{"Windows 3.1", 1992},
{"Windows NT 3.1", 1993},
{"Windows 95", 1995},
{"Windows NT 4.0", 1996},
{"Windows 95", 1995},
{"Windows 98", 1998},
{"Windows 1.0", 1985},
{"Windows 2000", 2000}
};
// Another way to call the range adaptor by using '|'
// Create a values_view that contains the year from each pair
for (int years : windows | std::views::values)
{
std::cout << years << ' '; // 1985 1987 1990 1992 ...
}
}
2003 2011 2014 2017 1998 2020
1985 1987 1990 1992 1993 1995 1996 1995 1998 1985 2000
Alias jenis adaptor rentang
all_t
Menyediakan jenis tampilan yang all
ditampilkan.
template <ranges::viewable_range R>
using all_t = decltype(views::all(std::declval<R>()));
Parameter
R
Jenis rentang yang mendasar.
Nilai hasil
Jenis tampilan yang all
mengembalikan: decltype(views::all(std::declval<R>()))
.
Contoh: all_t
#include <ranges>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v = {1,2,3,4,5,6,7,8,9,10};
auto myView = std::views::all(v);
std::views::all_t<decltype((v))> &viewType = myView;
}
Baca juga
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk