<ranges>
Yüksek düzeyde aralık, yineleme yapabileceğiniz bir şeydir. Aralık, aralığın başlangıcını işaretleyen bir yineleyici ve aralığın sonunu işaretleyen bir sentinel ile temsil edilir. Sentinel, başlangıç yineleyicisi ile aynı türde olabilir veya farklı olabilir. C++ Standart Kitaplığı'ndaki ve list
gibi vector
kapsayıcılar aralıklardır. Aralık, yineleyicileri Standart Şablon Kitaplığı'nı (STL) kullanma becerinizi basitleştirip güçlendirecek şekilde soyutlar.
STL algoritmaları genellikle koleksiyonun üzerinde çalışması gereken bölümüne işaret eden yineleyicileri alır. Örneğin, kullanarak std::sort()
a'yı vector
nasıl sıralayabileceğinizi düşünün. başlangıcını ve sonunu vector
işaretleyen iki yineleyici geçirirsiniz. Bu esneklik sağlar, ancak yineleyicileri algoritmaya geçirmek fazladan bir iştir çünkü muhtemelen her şeyi sıralamak istersiniz.
Aralıklarla çağrısı yapabilirsiniz std::ranges::sort(myVector);
. Bu, çağırdığınız std::sort(myVector.begin(), myVector.end());
gibi değerlendirilir. Aralık kitaplıklarında algoritmalar aralıkları parametre olarak alır (ancak isterseniz yineleyicileri de alabilirler). Doğrudan koleksiyonlar üzerinde çalışabilirler. içinde <algorithm>
kullanılabilen aralık algoritmalarına örnek olarak copy
, copy_n
, copy_if
, , all_of
, any_of
, , none_of
, , find_if_not
count_if
find_if
find
for_each
for_each_n
count
equal
ve mismatch
verilebilir.
Ancak belki de aralıkların en önemli avantajı, aralıklar üzerinde çalışan STL algoritmalarını işlevsel programlamayı anımsatabilecek bir stilde oluşturabilmenizdir.
Aralık örneği
Aralıklardan önce, belirli bir ölçüte sahip bir koleksiyonun öğelerini dönüştürmek istiyorsanız, işlemler arasında sonuçları tutmak için bir ara adım uygulamanız gerekirdi. Örneğin, üçe bölünebilen başka bir vektördeki öğelerden karelerden oluşan bir vektör oluşturmak istiyorsanız, şöyle bir şey yazabilirsiniz:
std::vector<int> input = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
std::vector<int> intermediate, output;
std::copy_if(input.begin(), input.end(), std::back_inserter(intermediate), [](const int i) { return i%3 == 0; });
std::transform(intermediate.begin(), intermediate.end(), std::back_inserter(output), [](const int i) {return i*i; });
Aralıklarla, vektöre gerek intermediate
kalmadan aynı şeyi gerçekleştirebilirsiniz:
// requires /std:c++20
std::vector<int> input = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
auto output = input
| std::views::filter([](const int n) {return n % 3 == 0; })
| std::views::transform([](const int n) {return n * n; });
Daha kolay okunmasının yanı sıra, bu kod vektör ve içeriği için gereken bellek ayırmayı intermediate
önler. Ayrıca iki işlem oluşturmanıza da olanak tanır.
Yukarıdaki kodda, üçe bölünebilen her öğe, bu öğenin karesini almak için bir işlemle birleştirilir. Boru (|
) simgesi işlemleri birbirine zincirler ve soldan sağa okunur.
sonucu, output
kendisi görünüm olarak adlandırılan bir aralık türüdür.
Görünümler
Görünüm basit bir aralıktır. Varsayılan yapı, taşıma inşaatı/ataması, kopya oluşturma/atama (varsa), imha, başlangıç ve bitiş gibi işlemlerin tümü, görünümdeki öğelerin sayısından bağımsız olarak sabit sürede gerçekleşir.
Görünümler, aşağıdaki bölümde ele alınan aralık bağdaştırıcıları tarafından oluşturulur. Çeşitli görünümler uygulayan sınıflar hakkında daha fazla bilgi için bkz . Sınıfları görüntüleme.
Görünümdeki öğelerin nasıl görüneceği, görünümü oluşturmak için kullandığınız aralık bağdaştırıcısına bağlıdır. Önceki örnekte, aralık bağdaştırıcısı bir aralık alır ve üçe bölünebilen öğelerin görünümünü döndürür. Temel alınan aralık değiştirilmez.
Görünümler, güçlü olan birleştirilebilir. Önceki örnekte, üçe bölünebilen vektör öğelerinin görünümü, bu öğelerin karelerini oluşturan görünümle birleştirilir.
Bir görünümün öğeleri tembelce değerlendirilir. Başka bir ifadeyle, bir görünümdeki her öğeye uyguladığınız dönüştürmeler, siz öğeyi sorana kadar değerlendirilmez. Örneğin, bir hata ayıklayıcıda aşağıdaki kodu çalıştırır ve ve satırlarına auto divisible_by_three = ...
auto square = ...
bir kesme noktası koyarsanız, içindeki her öğe input
üçe kadar bölünebilirlik için test edildiğinden lambda kesme noktasına isabet divisible_by_three
ettiğinizi görürsünüz. Lambda square
kesme noktası, üçe bölünebilen öğelerin karesi alınırken isabet alır.
// requires /std:c++20
#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 << '\n';
}
return 0;
}
Görünümler hakkında daha fazla bilgi için bkz <ranges>
. görünüm sınıfları.
Aralık bağdaştırıcıları
Aralık bağdaştırıcıları bir aralık alır ve bir görünüm oluşturur. Aralık bağdaştırıcıları, lazily olarak değerlendirilen görünümler üretir. Başka bir ifadeyle, görünümü oluşturmak için aralıktaki her öğeyi dönüştürme maliyetiniz yoktur. Görünümdeki bir öğeyi işleme maliyetini yalnızca bu öğeye eriştiğinizde ödersiniz.
Önceki örnekte, filter
aralık bağdaştırıcısı üçe bölünebilen öğeleri içeren adlı input
bir görünüm oluşturur. Aralık transform
bağdaştırıcısı üçe bölünebilen öğelerin görünümünü alır ve bu öğelerin karesini oluşturan bir görünüm oluşturur.
Aralık bağdaştırıcıları, aralıkların gücünün ve esnekliğinin kalbi olan birbirine zincirlenebilir (birleştirilebilir). Aralık bağdaştırıcıları oluşturma, önceki STL algoritmalarının kolayca birleştirilebilir olması sorununu gidermenize olanak tanır.
Görünüm oluşturma hakkında daha fazla bilgi için bkz . Aralık bağdaştırıcıları.
Aralık algoritmaları
Bazı aralık algoritmaları bir aralık bağımsız değişkeni alır. std::ranges::sort(myVector);
bunun bir örneğidir.
Aralık algoritmaları, ad alanında karşılık gelen yineleyici çifti algoritmalarıyla std
neredeyse aynıdır. Aralarındaki fark, kavram tarafından zorlanan kısıtlamalara sahip olmaları ve aralık bağımsız değişkenlerini veya daha fazla yineleyici-sentinel bağımsız değişken çiftini kabul etmeleridir. Doğrudan bir kapsayıcı üzerinde çalışabilir ve kolayca birbirine zincirlenebilirler.
<ranges>
işlevleri
Aralıklar için yineleyiciler ve sentineller oluşturmak ve bir aralığın boyutunu almak için aşağıdaki işlevler kullanılır.
İşlev | Açıklama |
---|---|
begin C++20 |
Aralıktaki ilk öğeye bir yineleyici alın. |
cbegin C++20 |
Aralıktaki ilk öğeye bir const yineleyici alın. |
cend C++20 |
-qualified aralığının sonundaki sentinel'i const alın. |
cdata C++20 |
const Bitişik aralıktaki ilk öğeye bir işaretçi alın. |
crbegin C++20 |
Aralığın başına ters const bir yineleyici alın. |
crend C++20 |
Dönüşlerin sonunda sentinel'i crbegin() alın. |
data C++20 |
Bitişik aralıktaki ilk öğeye bir işaretçi alın. |
empty C++20 |
Aralığın boş olup olmadığını belirleyin. |
end C++20 |
Aralığın sonundaki sentinel'i alın. |
rbegin C++20 |
Aralığın başına ters bir yineleyici alın. |
rend C++20 |
Aralığın sonundaki sentinel için ters yineleyici alın. |
size C++20 |
Aralığın boyutunu işaretsiz bir değer olarak alın. |
ssize C++20 |
Aralığın boyutunu imzalı değer olarak alır. |
Daha fazla bilgi için bkz <ranges>
. işlevler.
Aralık kavramları
Bir aralığın öğelerini nasıl yinelediğiniz, temel alınan yineleyici türüne bağlıdır. Aralıklar, hangi yineleyiciyi desteklediklerini belirten C++ kavramlarını kullanır.
C++20'de, X kavramının Y kavramını iyileştirdiğini söylemek, Y kavramını karşılayan her şeyin X kavramını da karşıladığını ifade eder. Örneğin: araba, otobüs ve kamyon tüm rafine araç.
Bazı aralık kavramları yineleyici kategorileri hiyerarşisini yansıtır. Aşağıdaki tabloda, uygulanabilecek kapsayıcı türleriyle birlikte aralık kavramları listelenmiştir.
Aralık kavramı | Açıklama | Desteklenen kapsayıcılar |
---|---|---|
std::ranges::output_range |
İleriye doğru yinelenebilir. | |
std::ranges::input_range |
Baştan sona en az bir kez yinelenebilir. | std::forward_list std::unordered_map std::unordered_multimap std::unordered_set std::unordered_multiset basic_istream_view |
std::ranges::forward_range |
Baştan sona birden çok kez yinelenebilir. | std::forward_list std::unordered_map std::unordered_multimap std::unordered_set std::unordered_multiset |
std::ranges::bidirectional_range |
İleri ve geriyi birden çok kez yineleyebilir. | std::list std::map std::multimap std::multiset std::set |
std::ranges::random_access_range |
işlecini kullanarak rastgele bir öğeye [] (sabit zamanda) erişebilir. |
std::deque |
std::ranges::contiguous_range |
Öğeler art arda bellekte depolanır. | std::array std::string std::vector |
Bu kavramlar hakkında daha fazla bilgi için kavramlara bakın.<ranges>
<ranges>
diğer ad şablonları
Aşağıdaki diğer ad şablonları bir aralık için yineleyici ve sentinel türlerini belirler:
Diğer ad şablonu | Açıklama |
---|---|
borrowed_iterator_t C++20 |
için range döndürülen yineleyicinin ömrü sona eren bir aralığa başvurup göndermediğini belirleyin. |
borrowed_subrange_t C++20 |
için subrange döndürülen yineleyicinin, ömrü sona eren bir alt düzenlemeye başvurup göndermediğini belirleyin. |
dangling C++20 |
Döndürülen yineleyicinin başvurduğu yaşam süresinden/subrange range daha uzun olduğunu gösterir.range /subrange |
iterator_t C++20 |
Belirtilen aralık türünün yineleyici türünü döndürür. |
range_difference_t C++20 |
Belirtilen aralığın yineleyici türünün fark türünü döndürür. |
range_reference_t C++20 |
Belirtilen aralığın yineleyici türünün başvuru türünü döndürür. |
range_rvalue_reference_t C++20 |
Belirtilen aralığın yineleyici türü için rvalue başvuru türünü döndürür. Başka bir deyişle, aralığın öğelerinin rvalue başvuru türü. |
range_size_t C++20 |
Belirtilen aralığın boyutunu raporlamak için kullanılan türü döndürür. |
range_value_t C++20 |
Belirtilen aralığın yineleyici türünün değer türünü döndürür. Veya başka bir deyişle, aralıktaki öğelerin türü. |
sentinel_t C++20 |
Belirtilen aralığın sentinel türünü döndürür. |
Bu diğer ad şablonları hakkında daha fazla bilgi için bkz <ranges>
. diğer ad şablonları.
Ayrıca bkz.
<ranges>
işlevleri
<ranges>
Kavram
Aralık bağdaştırıcıları
Üst bilgi dosyaları başvurusu