Thread overview
September 15, 2009

Şablon nedir ? Ne işe yarar ? Nasıl kullanılır ? Tabiki örnekler...
Yani şablonu A'dan Z'ye açıklarsanız sevinirim.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 15, 2009

Şablon [template] da dallı budaklı bir konu olduğu için ben ayrıntılarını daha sonra D.ershane'de anlatmayı düşünüyorum.

Burada en yaygın ve kolay kullanımını göstereceğim. D'nin şablonlarının C++'nınkilerden 16.7 kat :p daha güçlü ve kullanışlı olduklarını aklımızda tutarak... :)

C ve türevi diller tür konusunda sağlamcıdırlar. Türler arasından otomatik dönüşümler de olur ama int'ler için yazılmış bir ikili arama algoritması double'lar için çalışmaz. Ya her tür için ayrı bir fonksiyon yazmak gerekir, ya da qsort'un kulladığı void* gibi tür güvenliğini çöpe atan ara durumlara düşmek gerekir.

Şablonlar, algoritmanın bir kere yazılmasını ve uyan türlerin hepsi için çalışmasını sağlarlar.

Basit olsun diye 'büyüğünün_karesi' diye bir fonksiyon kullanacağım (burada ?: işlecinin anlamı da anlaşılıyordur herhalde):

int büyüğünün_karesi(int birinci, int ikinci)
{
   int büyük = (birinci > ikinci) ? birinci : ikinci;
   return büyük * büyük;
}

double büyüğünün_karesi(double birinci, double ikinci)
{
   double büyük = (birinci > ikinci) ? birinci : ikinci;
   return büyük * büyük;
}

Sonuçta her tür için ayrı bir fonksiyon yazmış olduk... Ama dikkat edilirse, fonksiyonun içeriği her tür için aynıdır. Şablon olanağı, derleyiciye "türün ismini şimdi söylemiyorum, sonra programdaki kullanışına bakarak sen anla; ve sanki ben her tür için ayrı ayrı yazmışım gibi derle" demek gibidir.

Şimdi int ve double demeden bu işi halledeceğiz. Geleneksel olarak, ismini söylemeden bıraktığımız türe T denir:

T büyüğünün_karesi(T)(T birinci, T ikinci)
{
   T büyük = (birinci > ikinci) ? birinci : ikinci;
   return büyük * büyük;
}

Tek bir fonksiyon yazmak yeter! :) Orada iki fark var:

  1. int veya double yerine T dedik
  2. Fonksiyonun ismini büyüğünün_karesi yerine büyüğünün_karesi(T) diye yazdık; bu, "T, kullanımına göre anlaşılacak olan bir türdür" demektir

Şimdi o tek fonksiyonu kullanarak hem int hem double için çağırabiliriz, ve derleyici o fonksiyondan kendisi iki adet üretir:

void main()
{
   büyüğünün_karesi(3, 4);
   büyüğünün_karesi(1.1, 2.2);
}

O kodda türlerin int ve double olduklarını derleyici anlar. Bazı durumlarda gerektiğinde türün ne olduğu elle yazılmak zorunda kalınabilir:

   büyüğünün_karesi!(int)(3, 4);

Tek parametre alan şablonlarda D'nin bir kestirme olanağı da var:

   büyüğünün_karesi!int(3, 4);

Yani şablon, algoritmayı (veya fonksiyonu) tek kere yazdığımız ve derleyicinin gereken türler için kod ürettiği bir düzenektir.

Sınıf şablonları da vardır ama benzerliğini göstermek dışında ayrıntıya girmeyeceğim:

import std.stdio;

class Çift(T)   // <-- T buraya koyulur
{
   T birinci_;
   T ikinci_;

   this(T birinci, T ikinci)
   {
       birinci_ = birinci;
       ikinci_ = ikinci;
   }

   void göster()
   {
       writeln("elimde iki adet ", T.stringof, " var: ",
               birinci_, " ve ", ikinci_);
   }
}

void main()
{
   auto int_çifti = new Çift!int(1, 2);
   int_çifti.göster();

   auto double_çifti = new Çift!double(1.1, 2.2);
   double_çifti.göster();
}

Tek bir sınıf yazdığımız halde int ve double için ayrı ayrı üretilir. Onun çıktısı şöyle:

elimde iki adet int var: 1 ve 2
elimde iki adet double var: 1.1 ve 2.2

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 16, 2009

Evet bu şablon çok güzel bir şeymiş. Eminim daha pek çok özelliğide vardır. Nede olsa dili geliştirenler arasında şablon ustalarıda var.

Siz demiştiniz ki "Kuvvetli tür denetimi [strongly type-safe] sağlayan dillerde derleme zamanında tür uyumluluğu şarttır. " Ama bu o duruma uymuyor değil mi ? Yani bu kodda tür dinamik statik değil.

void main()
{
   büyüğünün_karesi(3, 4);
   büyüğünün_karesi(1.1, 2.2);
}

Yani artık bütün programlama dilleri dinamik olanaklar sağlıyor. Buna örnek 'auto ' da var sanırım.

İnşallah dersleri çabuk yazarsanız. Dilde gerçekten güzel olanaklar var gibi duruyor. Bunu benim gibi cahil bile anlıyor :-) Ama dil gerçekten çok haraketli ve sanırım hatalarıda çok var. Ama ne demişler nerede haraket orada bereket.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 16, 2009

alias ne demek ve şablonda hangi amaç için kullanılıyor.

Birde :

static if (is (T : double) || is (T : float))

Burada is harelde şablonun türü double yada float mı girdi diye bakıyor. is başka nerelerde kullanılabilir. Mesela ben asas değişkenini int olarak mı tanımlandığını öğrenmek için

is(asas : int)

mi diyeceğim.

Birde if'in neden static tanımlandığını anlamadım.

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 16, 2009

Yanlış anlam çıkmış... :) Tam tersine, şablonlar tür güvenliği konusunda hiçbir taviz vermezler. Bütün olay derleme zamanında kod üretilerek halledildiği için,

   büyüğünün_karesi(3, 4);
   büyüğünün_karesi(1.1, 2.2);

çağrıları iki farklı ve türleri sapasağlam fonksiyonlar çağırırlar.

auto'da endişe edecek bir şey yok: o da yalnızca programcının gereksizce yazacağı türlerin külfetini ortadan kaldırır. Yine derleme zamanında ve sanki programcı yazmış gibi, doğru tür yazılır.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

September 16, 2009

'static if''i birlikte tek bir anahtar sözcük gibi düşünebilirsin. Derlemeli dillerde 'static'in bir anlamı, "derleme zamanında" demektir.

'static if' de if gibidir ama derleme zamanında çalışır. C++'nın şablonlarıyla karşılaştırıldığında D'ye olağanüstü güç getiriyor.

Oradaki ifade, "eğer T double veya float ise" anlamına geliyor.

alias'ın da birden fazla anlamı var. Kendim öğrendikçe yazarım. :) Ama kelime anlamı olarak "takma isim" demek...

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]