Decltype vs Auto: Template Kodda Tür Çıkarımında Doğru Aracı Seçmek

C++'ta template kod yazarken auto ve decltype ikisi de tür çıkarımı yapıyor, ama aynı işi yapmıyorlar. Bu farkı anlamadan yazılan kod ya referans kaybediyor, ya da beklenmedik const/volatile özellikleri taşıyor.

auto

bir değişken bildirimidir. Derleyici sağ tarafı değerlendirir ve uygun türü atanır. Ama referans ve const bilgisini atıyor:

1int x = 5;
2int& ref = x;
3
4auto a = ref; // int, referans kayboldu
5auto& a2 = ref; // int&, referans korundu

decltype ise tam olarak ne gördüğünü rapor eder. Referans, const, hepsi korunur:

1decltype(ref) d = ref; // int&, referans korundu
2decltype(x) d2 = x; // int

Fark önemli mi? Evet. Bir template'de yanlış tür seçimi, beklenmedik kopya oluşturabilir, performans düşürebilir veya kodun çalışmasını durdurabilir.

Bir generic forward fonksiyonu düşün:

1template<typename T>
2void process(T&& arg) {
3auto result = some_function(arg);
4// result'ün türü ne?
5}

Eğer some_function bir referans döndürüyorsa ve siz auto kullandıysanız, referans kaybolur. Sonra result üzerinde değişiklik yaparsanız, orijinal nesneyi etkilemezsiniz. Hata bulunması zor.

decltype

kullanırsanız:

Reklam · TEST
AdSense Test ReklamıYazı arası (gönderi içi) · Yazı arası
1decltype(some_function(arg)) result = some_function(arg);

Bu, some_function'ın döndürdüğü türü tam olarak alır. Referans varsa korunur.

Modern C++'ta sık karşılaşılan bir pattern, trailing return type'tır:

1template<typename T, typename U>
2auto add(T a, U b) -> decltype(a + b) {
3return a + b;
4}

Burada decltype(a + b) dönüş türünü dinamik olarak belirler. auto tek başına bunu yapamaz; derleyici a + b'nin türünü tahmin etmeye çalışır ama template parametreleri tam net değilse başarısız olabilir.

C++14+ ile auto dönüş türü de mümkün ama her durumda güvenli değildir. decltype daha açık ve niyeti belirtir.

auto kullan:

  • Basit, yerel değişkenlerde (int, string gibi)
  • Referans kaybı sorun değilse
  • Kod okunabilirliği önemli ve tür açık ise

decltype kullan:

  • Template'lerde, özellikle generic kod yazıyorsan
  • Referans, const, volatile gibi nitelikler önemli ise
  • Dönüş türü başka bir ifadenin türüne bağlı ise
  • Trailing return type pattern'de
auto

rahat ve kısa, ama decltype daha kesin. Template kod yazıyorsan, ki bu C++'ta kaçınılmaz, decltype'ın ne yaptığını bilmek zorunlu. Referans kaybı, sessiz hata olur; çoğu zaman runtime'da fark edersin. Başlangıçta biraz verbose görünse de, decltype template kodunda güvenilir ve kasıtlıdır. Onu anlamak, C++ template mastery'nin ilk adımı.

Reklam · TEST
AdSense Test ReklamıGönderi altı · Görüntülü
konu hakkında tepkinizi verebilirsiniz
  • geceyolcusu

    Referans kaybetme sorunu gerçekten insanı şaşırtabiliyor Perfect forwarding yapan bir

  • adlı kullanıcıya yanıt verdi
    biriktirdiklerim

    Ayy evet ben de bunu yaşadım auto kullanıp da referans kaybolunca değişken kopyalanıyor sonra niye yazı yavaş diye iki saat harcamıştım decltypeı

  • adlı kullanıcıya yanıt verdi
    geceyolcusu

    İki saat harcaman tamamen haklı auto ile referans kaybı fark etmesi gerçekten zor çünkü kod çalışıyor sadece yavaş decltype öğrenince açılıyor abi

  • adlı kullanıcıya yanıt verdi
    biriktirdiklerim

    offf aynen kodun çalışması seni aldatıyor işte hata da vermediği için iki saat sonra performans profilinde görüyorsun çok fazla kopyalama olduğunu