Aracılığıyla paylaş


<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 listgibi 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 vectoriş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_notcount_iffind_iffindfor_eachfor_each_ncountequalve mismatchverilebilir.

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, outputkendisi 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
beginC++20 Aralıktaki ilk öğeye bir yineleyici alın.
cbeginC++20 Aralıktaki ilk öğeye bir const yineleyici alın.
cendC++20 -qualified aralığının sonundaki sentinel'i constalın.
cdataC++20 const Bitişik aralıktaki ilk öğeye bir işaretçi alın.
crbeginC++20 Aralığın başına ters const bir yineleyici alın.
crendC++20 Dönüşlerin sonunda sentinel'i crbegin() alın.
dataC++20 Bitişik aralıktaki ilk öğeye bir işaretçi alın.
emptyC++20 Aralığın boş olup olmadığını belirleyin.
endC++20 Aralığın sonundaki sentinel'i alın.
rbeginC++20 Aralığın başına ters bir yineleyici alın.
rendC++20 Aralığın sonundaki sentinel için ters yineleyici alın.
sizeC++20 Aralığın boyutunu işaretsiz bir değer olarak alın.
ssizeC++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_tC++20 için range döndürülen yineleyicinin ömrü sona eren bir aralığa başvurup göndermediğini belirleyin.
borrowed_subrange_tC++20 için subrange döndürülen yineleyicinin, ömrü sona eren bir alt düzenlemeye başvurup göndermediğini belirleyin.
danglingC++20 Döndürülen yineleyicinin başvurduğu yaşam süresinden/subrange rangedaha uzun olduğunu gösterir.range/subrange
iterator_tC++20 Belirtilen aralık türünün yineleyici türünü döndürür.
range_difference_tC++20 Belirtilen aralığın yineleyici türünün fark türünü döndürür.
range_reference_tC++20 Belirtilen aralığın yineleyici türünün başvuru türünü döndürür.
range_rvalue_reference_tC++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_tC++20 Belirtilen aralığın boyutunu raporlamak için kullanılan türü döndürür.
range_value_tC++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_tC++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