Modern C++ Feature Part1

Kerim Fırat
3 min readApr 30, 2022

Birçok konuda olduğu gibi,modern cpp konularında da yeterince türkçe kaynak olmadığı için “Modern C++” başlığı ile oluşturmuş olduğum yazı serisinin ilk bölümünü işleyeceğiz.

#include<variant>

Cpp17 ile birlikte gelen bu özellik esnek bir template yapısı ile tasarlanmıştır. Görevi ise isminden de tahmin edilebileceği gibi,farklı biçimde-tipte birden fazla veri türü ve/veya nesneyi aynı anda tek değişken altında tutmaktır.
Soru: Bu ne demek?
Cevap: Bir değişken veya tanımlamayı birden fazla tipte aynı anda kullanmak istiyorsak ve bu amaca hizmet edecek bir yapıyı kolaylıkla,belki tek satırda halletmek istiyorsak “variant” oldukça faydalı bir özelliktir.
Genel tanımlama biçimi aşağıdaki gibidir.

Yaptığımız tanımlama ve kullanım üzerinden detaya inmeden evvel,variant’ın ana yapısı aşağıda verilmiştir.

template<class… Types>

Basit template konularına hakim bir programcının da genel itibariyle “variant” yapısını kolaylıkla çözdüğünü ve mimari açıdan yaklaşık olarak tahminlerde bulunabileceğini düşünüyorum. Daha detaylı incelemek isteyenler header dosyası üzerinden ilerleyebilirler.

Yukarıda yaptığımız basit tanımlama,iki adet veri(int,bool) türünü aynı anda destekleyecek niteliktedir. Yani artık “v” değişkenine hem int türünden değer,hem de “bool” türünden değer atayabilir ve kullanabiliriz.Dolayısıyla aşağıdaki gibi atamalar doğdurur:

Bir başka tanımlama ve değer atama örnekleri aşağıda yer almaktadır.

Görüldüğü üzere yapı oldukça basit ancak iş görecek nitelikte. Dolayısıyla “variant” feature,bu gibi esnek kullanımlar için özel bir class tasarımı yapmaktan kurtarıyor.

Yukarıdaki değer atamalarında dikkat etmemiz gereken bazı husular vardır. Variant tanımlarken,tanımlanan veri türü dışında bir tür ataması yapılamaz. Bir diğer husus ise,variant’a en son atanan değer geçerlidir ve okuma yapılırken de en son atanan veri tipine bağlı kalarak değer çağrılmalıdır.Yani en son atanan değer,önceki tüm atamaları geçersiz kılar.
Dolayısıyla atanan değere bağlı olarak tüm hareketler şöyledir:

Fonksiyonlar:

variant class’ı aşağıda verilen fonksiyonlara sahiptir.Tüm fonksiyonları incelemek için sayfa altında verilen kaynak linklerden ulaşılabilir.

-constexpr std::size_t index() const noexcept; Bu fonksiyon,variant tanımlarken belirtilen tip-tür’ün index değerini döner. Genel yapısı ve kullanımı aşağıdaki gibidir.

Output:
v.index: 2

Output:
v.index: 1

-constexpr bool holds_alternative( const std::variant<Types…>& v ) noexcept; variant’ın en son tuttuğu tipi kontrol eder. Örnek tanımlama ve kullanımı aşağıdaki gibidir.

Output:
tuttuğu tip-değer int mi?:0 //yani false

Çıktıyı incelediğimizde mevcut tutulan değer-tip’in int olmadığını görüyoruz.
Çünkü bir satır önce “v = true” şeklinde bir atama yapmıştık. Dolayısıyla aşağıdaki bir kullanım çıktısı 1(true) olacaktır.
Örnek:

Output:
tuttuğu tip-değer bool mi?:1 //yani true

-constexpr T& get( std::variant<Types…>& v );
Get fonksiyonu belirtilen tipte nesne döndürür.
Örnek:

Get fonksiyonu kullanılırken,son işlem yapılan tür-tip dikkate alınmalıdır.
Aksi halde “bad_variant_access” hatası fırlatacaktır.Aşağıda get fonksiyonu hatalı kullanılmıştır.

Output:
Exception: Unexpected index

-constexpr std::add_pointer_t<T> get_if( std::variant<Types…>* pv ) noexcept;
get_if fonksiyonu belirtilen tip-türe ait veri varsa getirir. Ayrıca “bad_variant_access” exception yaşmamak için kullanılır.
Örnek:

-std::variant_size, std::variant_size_v:Variant boyutunu döndürür.
Örnek:

Output:
variant size:4

Yazı boyunca genel tür-tip tanımlayarak variant oluşturduk. Ancak yazının başından da belirttiğim ve aşağıda verdiğim kaynakları incelerseniz,variant yapısının template olduğunu ve dolayısıyla tanımlama esnasında tür-tip belirlemekte özgür olabileceğinizi göreceksiniz. Dolayısıyla aşağıda verilen örnek doğdurdur. Örnek:

Açık söylemek gerekirse modern Cpp özelliklerinden bazılarını tasarımsal olarak zayıf buluyorum. Variant özelliği de bunlardan biridir ve gelecek Cpp sürümlerinde variant da dahil bazı mevcut özellikler üzerinden güçlü değişiklikler olacağını düşünüyorum. Bağımsız olarak Cpp tasarımı üzerinde bir süredir çalışmalar yapmaktayım. Belki yazı-makale olarak değil de,vlog tarzı içeriklerle kendi tasarımlarım üzerinden karşılaştırmalar yapmayı düşünüyorum.

KAYNAKLAR:
https://en.cppreference.com/w/cpp/utility/variant
https://en.cppreference.com/w/cpp/header/variant

-end of

--

--

Kerim Fırat

Senior C++,Android Platform(AOSP,AAOS) Developer,Performance Architect,Open Source Contributor | Turkey Java User Group Vice Chairman | Author