tuple sınıf şablonu

Bu yazımızda 2011 standartlarıyla C++ diline resmi olarak eklenen tuple sınıf şablonunu ele alacağız:
Standart kütüphanenin pair yapısı iki ayrı değerin tek bir birim olarak kullanılmasını sağlıyor. pair yapısı standart kütüphane tarafından birçok yerde kullanılıyor. Örneğin bazı standart işlevler çağıranına iki ayrı değer iletmek üzere geri dönüş değerleriyle bir pair döndürüyorlar. Standart kütüphanenin map, multimap, unordered_map ve unordered_multimap kapları pair nesneleri tutuyorlar. Standart kütüphanenin tuple başlık dosyasında tanımlanan tuple şablonu işi biraz daha ileriye götürerek, istenen sayıda ve istenen herhangi türde öğenin bir arada tutulmasına olanak sağlıyor:

tuple‘da tutulan öğelere global get işlev şablonuyla erişebiliyoruz.  get işlev şablonu sabit şablon parametresine (template nontype parameter) sahip olduğundan get ismini izleyen açısal ayraç içinde bir sabit ifadesinin kullanılması zorunlu. tuple içinde tutulan ilk öğenin indeksi 0. Açısal ayraç içinde geçersiz bir tuple indeksinin kullanılması doğrudan sentaks hatası. get işlevinin geri dönüş değeri referans olduğundan bu işlev ile tuple‘da tutulan öğenin kendisine erişiyoruz:

tuple sınıfının varsayılan kurucu işlevi,tuple öğelerini bu öğelerin ait olduğu sınıfların varsayılan kurucu işlevleriyle hayata getiriyor. Eğer bir tuple öğesi doğal veri türlerinden ise hayata 0 değeriyle başlıyor:

Sınıfın bir de parametreli kurucu işlevi var. Bu kurucu işlevle tuple nesnesinin her bir öğesini istediğimiz değerlerle hayata başlatabiliyoruz:

İstediğimiz değerlerle bir tuple nesnesi oluşturmanın daha pratik yolu make_tuple işlev şablonu. Bu işlev şablonunun kullanılması durumunda, derleyici işlev çağrısında kullanılan argumanlarının türünden hareketle bir çıkarım yaparak geri döndürülecek tuple nesnesinin türünü derleme zamanında saptıyor:

Yukarıdaki kodda auto anahtar sözcüğüyle tanımlanan t nesnesi

türünden.

Bir tuple nesnesi içinde doğrudan referans da tutabiliyor. Aşağıdaki kodu inceleyin:

tuple nesnesini oluşturmak için yardımcı make_tuple işlevinin kullanılması durumunda, oluşacak tuple nesnesinde referans tutulabilmesi için, <functional> başlık dosyasında tanımlanan ref ya da cref  işlev şablonlarının kullanılması gerekiyor:

Elimizde bulunan bir tuple nesnesinin öğelerini kendi değişkenlerimize aktarmak istiyoruz. Bunu nasıl yapabiliriz?

Bunu yapmanın bir başka yolu da make_tuple işleviyle içinde referans tutan bir tuple nesnesi oluşturmak ve oluşturduğumuz tuple nesnesine, değerlerini çekmek istediğimiz diğer tuple nesnesini atamak:

Standart kütüphanenin tuple başlık dosyasında bulunan tie işlevi işimizi kolaylaştırarak bunu bizim için yapıyor:

Ne olduğunu anladık mı? make_tuple işlevine yapılan aşağıdaki çağrıyla

tie işlevine yapılan aşağıdaki çağrının birbirine eşdeğer olduğunu düşünebilirsiniz.

Peki ya tuple nesnesinde tutulan bazı öğeleri kullanmadan yalnızca istediğimiz öğeleri tuple nesnesinden çekmek istiyorsak ne yapacağız? Standart kütüphane bunun için şöyle bir hile yapmış: tuple başlık dosyasında bildirilen, derleyicinin belirlediği bir türden, ismi ignore olan bir nesne var. Bu nesneye herhangi türden bir değer geçerli olarak atanabiliyor ve bu nesneye yapılan atamalar herhangi bir yan etki oluşturmuyor. Aşağıdaki kodu derlediğinizde hiçbir sentaks hatası almayacaksınız:

Çekmek istemediğimiz tuple öğeleri için tie işlevine std::ignore nesnesini göndermemiz yeterli:

tuple sınıfının belki de en çok işe yaradığı yer bir işlevin birden fazla değeri bir tuple nesnesi ile geri döndürmesi. Aşağıdaki işlev bildirimine bakın:

Bildirilen get_no_name_ave işlevi tuple<int, string, double> türüne geri dönerek kendisini çağıran koda bir tamsayı, bir string, bir de gerçek sayı döndürecek. Şimdi de bu işlevi çağıran koda bakalım:

Kabul edin, çok şık.

Şimdi aşağıdaki idiyoma bakın ve ne yapıldığını anlamaya çalışın:

pair nesnelerini karşılaştırabildiğimiz gibi tuple nesnelerini de tüm karşılaştırma işleçleriyle karşılaştırabiliyoruz. Karşılaştırma lexicographical compare algoritmasıyla yapılıyor. Yani iki tuple nesnesinden birinci öğesi daha küçük olan diğerinden küçüktür. Eğer birinci öğeler eşit ise ikinci öğesi daha küçük olan diğerinden küçüktür. Eğer…

tuple başlık dosyasında bulunan tuple_size isimli sınıf şablonunun value isimli öğesi bir derleme zamanı sabiti olarak tuple içinde tutulan öğe sayısını veriyor. Bir tuple içinde tutulan öğe sayısını bir sabit ifadesi olarak kullanmak için tek yapmamız gereken tuple_size şablonunun tuple türümüz için açılımı olan sınıfın value isimli öğesini kullanmak:

Yukarıdaki kodda tuple nesnesinin öğe sayısı constexpr olarak tanıtılan n değişkenine ilk değer vermekte kullanılıyor. n değişkeni constexpr olarak tanıtıldığından, ilk değer verici olarak kullanılan ifade bir sabit ifadesi olmasaydı bildirim geçersiz olacaktı.

tuple başlık dosyasında bildirilen bir başka yardımcı sınıf şablonu tuple_element:

Bu sınıf şablonunun type isimli öğesi tuple içinde tutulan belirli bir indeksli öğenin tür bilgisini derleme zamanında veriyor:

İki öğesi olan bir tuple nesnesine uygun türden bir pair nesnesini atayabiliyoruz:

tuple_cat işleviyle tuple nesnelerini birbirleriyle ya da pair nesneleriyle birleştirebiliyoruz:

Yukarıdaki kodda tanımlanan t3 nesnesinin türünün ne olduğunu söyleyebilir misiniz?

Son olarak biraz “template metaprogramming” yapalım. Aşağıdaki kodda bir tuple nesnesinin tüm öğelerini çıkış akımına besleyecek global bir operator<< işlevi şablonu ve bu şablona yardımcı olan DisplayTuple isimli sınıf şablonu yer alıyor.
Bir başka yazımızda değişken sayıda parametreye sahip olan şablonları ayrıntılı olarak ele alacağız.

Necati Ergin

C ve Sistem Programcıları Derneğinde eğitmen olarak çalışıyor.

Bunlar da ilginizi çekebilir

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Kod Eklemek İçin Okuyun