Aracılığıyla paylaş


<ranges> sınıfları görüntüleme

Görünüm, sahip olmadığı öğelere (hariç) owning_viewbaşvuran basit bir aralıktır. Görünüm genellikle başka bir aralığı temel alır ve ister dönüştürerek ister filtreleyerek farklı bir bakış açısı sağlar. Örneğin, std::views::filter başka bir aralıktaki öğeleri seçmek için belirttiğiniz ölçütleri kullanan bir görünümdür.

Görünümdeki öğelere eriştiğinizde, bu işlem "lazily" yapılır, böylece iş yalnızca bir öğe aldığınızda yapılır. Bu, performans cezası olmadan görünümleri birleştirmeyi veya oluşturmayı mümkün kılar.

Örneğin, bir aralıktan yalnızca çift öğeleri sağlayan bir görünüm oluşturabilir ve sonra bunları kareköte ederek dönüştürebilirsiniz. Filtreleme ve dönüştürme işlemi yalnızca eriştiğiniz öğeler için ve yalnızca bunlara eriştiğiniz zaman yapılır.

Bir görünüm, kaç öğe içerdiği fark etmez, sabit sürede kopyalanabilir, atanabilir ve yok edilebilir. Bunun nedeni, bir görünümün başvurduğu öğelere sahip olmamasıdır, bu nedenle bir kopya oluşturması gerekmez. Bu nedenle, performans cezası olmadan görünüm oluşturabilirsiniz.

Genellikle bir aralık bağdaştırıcısı kullanarak bir görünüm oluşturursunuz. Aralık bağdaştırıcıları, görünüm oluşturmanın amaçlanan yoludur, görünüm sınıflarını doğrudan örneklemekten daha kolaydır ve bazen görünüm sınıflarını doğrudan örneklemekten daha verimlidir. Görünüm sınıfları, var olan bir görünüm türüne göre kendi özel görünüm türünüzü oluşturmanız gerektiğinde doğrudan kullanıma sunulur.

Bir vektörde üçe bölünebilen öğelerin karelerinin görünümünü oluşturmaya ilişkin kısa bir örnek aşağıda verilmiştir:

// 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
    }
}
0 9 36 81

Temel alındığı aralık değiştirildikten sonra bir görünüm kullanmak tanımsız davranışa yol açabilir. Örneğin, temel alınan vektöre öğe ekler veya kaldırırsanız, reverse_view vektöre dayalı bir öğe yeniden kullanılamaz. Temel alınan vektörde değişiklik yapıldığında, görünümün yapmış olabileceği yineleyicinin kopyası dahil olmak üzere kapsayıcının end yineleyicisi geçersiz kılınır.

Görünümleri oluşturmak ucuz olduğundan, temel alınan aralığı değiştirirseniz genel olarak bir görünümü yeniden oluşturmanız gerekir. Aşağıdaki örnekte, bir görünüm işlem hattını yeniden kullanabilmeniz için bir değişkende depolama gösterilmektedir.

// requires /std:c++20 or later
#include <iostream>
#include <ranges>
#include <vector>
#include <list>
#include <string_view>
#include <algorithm>

template<typename rangeType>
void show(std::string_view msg, rangeType r)
{
    std::cout << msg;
    std::ranges::for_each(r,
        [](auto e)
        {
            std::cout << e << ' ';
        });
    std::cout << '\n';
}

int main()
{
    std::vector v{ 1, 2, 3, 4 };
    show("v: ", v);

    // You can save a view pipeline
    auto rev3 = std::views::take(3) | std::views::reverse;

    show("v | rev3: ", v | rev3); // 3 2 1

    v.insert(v.begin(), 0); // v = 0 1 2 3 4
    show("v: ", v);

    // Because modifying the vector invalidates its iterators, rebuild the view.
    // We are reusing the view pipeline we saved earlier
    show("v | rev3(v): ", rev3(v));
}
v: 1 2 3 4
v | rev3: 3 2 1
v: 0 1 2 3 4
v | rev3(v): 2 1 0

Aşağıdaki görünüm sınıfları ad alanında std::ranges tanımlanır.

Göster Açıklama
basic_istream_view C++20 Giriş akışından ardışık öğelerin görünümü. Uzmanlık alanları arasında ve istream_viewbulunurwistream_view.
common_view C++20 Farklı yineleyici/sentinel türleri olan bir görünümü aynı yineleyici/sentinel türlerine sahip bir görünüme uyarlar.
drop_view C++20 Başka bir görünümden oluşturulur ve ilk count öğeler atlanır.
drop_while_view C++20 Başka bir görünümden oluşturulur ve koşul geçerli olduğu sürece öndeki öğeler atlanır.
elements_view C++20 Seçili dizin üzerinde bir koleksiyondaki tanımlama grubu benzeri her değere bir görünüm. Örneğin, bir değer aralığı std::tuple<string, int> göz önünde bulundurulduğunda, her bir tanımlama grubundaki string tüm öğelerden oluşan bir görünüm oluşturun.
empty_view C++20 Öğe içermeyen bir görünüm.
filter_view C++20 Bir koşulla eşleşmeyen bir aralığın öğelerini filtreler.
iota_view C++20 Artımlı değerler dizisi içeren oluşturulan görünüm.
join_view C++20 Birden çok aralığın tüm öğelerini tek bir görünümde birleştirir.
keys_view C++20 Bir koleksiyondaki her tanımlama grubu benzeri değere ilk dizin üzerinden bir görünüm. Örneğin, bir değer aralığı std::tuple<string, int> göz önünde bulundurulduğunda, her bir tanımlama grubundaki string öğelerden oluşan bir görünüm oluşturun.
lazy_split_view C++20 Bir görünümü sınırlayıcıya göre alt bölümlere böler.
owning_view C++20 Öğelerin sahipliğini başka bir aralıktan alır.
ref_view C++20 Başka bir aralığa ait öğelere başvuran bir görünüm.
reverse_view C++20 Bir aralığın öğelerini ters sırada sunar.
single_view C++20 Yalnızca bir öğe içeren bir görünüm.
split_view C++20 Bir görünümü sınırlayıcıya göre alt bölümlere böler.
subrange C++20 Başlangıç yineleyicisi ve sentinel tarafından tanımlanan aralık öğelerinin bir bölümünün görünümü.
take_view C++20 Bir aralığın önünden alınan belirtilen öğe sayısını içerir.
take_while_view C++20 Verilen koşulla eşleşen bir aralığın önde gelen öğelerini içerir.
transform_view C++20 Her öğeye bir dönüştürme işlevi uygulandıktan sonra temel alınan sıranın görünümü.
values_view C++20 Bir koleksiyondaki her tanımlama grubu benzeri değere ikinci dizin üzerinden bir görünüm. Örneğin, bir değer aralığı std::tuple<string, int> göz önünde bulundurulduğunda, her bir tanımlama grubundaki int öğelerden oluşan bir görünüm oluşturun.

Bu sınıfların birçoğunun ad alanında bunların örneklerini oluşturan karşılık gelen std::views vardır. Doğrudan görünüm sınıfları oluşturmak yerine görünüm oluşturmak için bağdaştırıcı kullanmayı tercih edin. Aralık bağdaştırıcıları, görünüm oluşturmanın amaçlanan yoludur, kullanımı daha kolaydır ve bazı durumlarda daha verimlidir.

Sınıf özelliklerini görüntüleme

Her görünüm sınıfı konusunun söz dizimi bölümünden sonra bir Özellikler bölümü vardır. Özellikler bölümünde aşağıdaki girdiler vardır:

  • Aralık bağdaştırıcısı: Görünümü oluşturan aralık bağdaştırıcısının bağlantısı. Genellikle doğrudan görünüm sınıfı oluşturmak yerine görünüm oluşturmak için aralık bağdaştırıcısı kullanırsınız, bu nedenle kolaylık sağlamak için burada listelenir.

  • Temel aralık: Görünümlerin, kullanabilecekleri temel aralık türü için farklı yineleyici gereksinimleri vardır. Yineleyici türleri hakkında daha fazla bilgi için bkz . aralık yineleyici hiyerarşisi .

  • Görünüm yineleyici kategorisi: Görünümün yineleyici kategorisi. Görünüm bir aralığı uyarladığında, görünümün yineleyici türü genellikle temel aralığın yineleyici türüyle aynıdır. Ancak, bazı görünümler için farklı olabilir. Örneğin, reverse_view temel alınan aralığın bir bidirectional_iteratordeğeri olsa bile bir random_access_iteratordeğeri vardır.

  • Öğe türü: Görünümün yineleyicisinin döndürdüğü öğelerin türü.

  • Boyutlandırılmış: Görünümün başvurduğu öğe sayısını döndürip döndüremeyeceği. Tüm görünümler bunu yapabilir.

  • Ortak aralık: Görünümün bir common_rangeolup olmadığını belirtir; bu, başlangıç yineleyicisi ve sentinel türlerinin aynı olduğu anlamına gelir. Ortak aralıklar, yineleyici çiftleriyle çalışan aralık öncesi kodlar için kullanışlıdır. Örneğin, gibi vector(ranges::begin(x), ranges::end(x))bir dizi kapsayıcısı için yineleyici çift oluşturucularıdır.

  • Ödünç alınan aralık: Görünümün ödünç alınan bir aralık olup olmadığını belirtir. borrowed_range<T>, yineleyicileri yok edildikten sonra T için T kullanabileceğiniz anlamına gelir.

    Hiçbir standart kapsayıcı ödünç alınan bir aralık değildir, çünkü kapsayıcıyı yok etmek öğeleri boşaltır ve yineleyicileri geçersiz kılır. Bu durumda, yineleyicilerin yıkımdan sonra "sallanma" olarak bırakıldığını söyleriz.

    Örneğin, std::ranges::find() genellikle aralık bağımsız değişkenindeki bulunan öğeye bir yineleyici döndürür. Aralık bağımsız değişkeni geçici (rvalue) bir kapsayıcıysa, döndürülen yineleyiciyi depolamak ve daha sonra kullanmak bir hatadır çünkü "sallanıyor".

    Yineleyicileri (veya alt aralıkları) döndüren aralık algoritmaları bunu yalnızca bağımsız değişkenleri lvalues (geçici olmayan) veya ödünç alınan aralıklar olduğunda yapar. Aksi takdirde, bir yineleyici gibi kullanmayı denediğinizde neyin yanlış gittiğine ilişkin hata iletilerinde ipucu sağlayan bir nesne döndürürler std::dangling .

  • const mi: Görünümün bir const örneğini yineleyip yinelemeyebileceğinizi gösterir. Tüm const görünümler yinelenemez. Bir görünüm yinelenebilir değilseconst, görünüme başvuru alan ve sonra yinelemeyi deneyen bir for (const auto& element : as_const(theView)) işlevle const yineleme yapamaz veya bu işleve geçiremezsiniz.

Aralık yineleyici hiyerarşisi

Her görünüm sınıfı konusunun Özellikler bölümünde, Temel aralık ve Görünüm yineleyicisi kategorisindeki yineleyici kategorisi, aralığın/görünümün desteklediği yineleyici türüne başvurur. C++20 kavramları tarafından tanımlanan altı Aralık yineleyici kategorisi vardır. Aralık yineleyicilerinin hiyerarşisi, artan özellik sırasına göre şöyledir:

Aralık yineleyicisi kavramı Açıklama
output_range Yalnızca yazma, yalnızca ileriye taşıma; tek geçişli.
input_range Salt okunur, yalnızca ileriye doğru hareket eder; tek geçişli.
forward_range Yalnızca ileri doğru hareket eder; çoklu geçiş.
bidirectional_range İleri ve geri hareket edebilir; çoklu geçiş.
random_access_range Koleksiyona bir dizinle erişebilir; çoklu geçiş.
contiguous_range Koleksiyona bir dizinle erişebilir ve öğeler bellekte bitişik olarak depolanır.

Genel olarak bakıldığında, yineleyici, tabloda kendisinden önce gelen yineleyicilerin özelliğine sahiptir. Örneğin, bidirectional_range özelliklerine forward_rangesahiptir, ancak tam tersi değildir. bir öğesine yazamadığınız input_rangeiçin özelliğine output_range sahip olmayan dışındainput_range.

"Gerekli input_range veya daha yüksek" deyimi, görünümün bir , input_range, forward_range, bidirectional_rangeveya random_access_range yineleyici ile contiguous_rangekullanılabileceğini gösterir, çünkü hepsi kadar input_rangeyeteneklidir.

Aralık yineleyici hiyerarşisi, yineleyici hiyerarşisi ile doğrudan ilişkilidir. Daha fazla bilgi için bkz . Yineleyici kavramları.

Ayrıca bkz.

<ranges>
Aralık bağdaştırıcıları