Forum: D Programlama Dili RSS
Şablon özellemeleri immutable'ı gözardı ediyor
acehreli (Moderatör) #1
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Şablon özellemeleri immutable'ı gözardı ediyor
Şablonlar çok güzel bir olanak ve C++'dakilerden çok daha güçlü.

Şablorlar dersini mutlu mutlu yazarken bir sorunla karşılaştım. Şimdi Digital Mars haber grubundan sordum bakalım mantıklı bir açıklaması varmıymış...

Sorun şu: Girişten istediğim türde bir değer okuyan bir şablon yazıyoruz:

import std.cstream;
 
 
T giriştenOku(T)(string soru)
{
    dout.writef(soru, ": ");
 
    T cevap;
    din.readf(&cevap);
 
    return cevap;
}
 
void main()
{
    auto yaş = giriştenOku!int("Yaşınız?");
}

int, double, kendi türlerimiz, vs. için gayet güzel çalışıyor. Ama string için çalışmıyor. string'in elemanları immutable char oldukları için, şablon içindeki din.readf çağrısı parçalama hatasına (segmentation fault) neden oluyor.

Mantıklı... O zaman şablonların özelleme (specialization) olanağından yararlanarak string için özel bir tanımını veriyoruz:

T giriştenOku(T : string)(string soru)
{
    // ... öncekinin tekrarı olabilir; ama .idup döndürmesi gerek:
    return cevap.idup;
}

(T : string), bu tanımın şablonun string özellemesi olduğunu belirtiyor.

Sorun bu noktada ortaya çıkıyor: dmd char[] türü için de aynı özellemeyi seçiyor ve bu sefer de sonundaki .idup, char[] için sorun oluşturuyor.

Sorunlu bütün bir program:

import std.cstream;
 
T giriştenOku(T)(string soru)
{
    dout.writef(soru, ": ");
 
    T cevap;
    din.readf(&cevap);
 
    return cevap;
}
 
T giriştenOku(T : string)(string soru)
{
    dout.writef(soru, ": ");
 
    T cevap;
    din.readf(&cevap);
 
    return cevap.idup;
}
 
void main()
{
    auto isim = giriştenOku!string("İsminiz?");
    auto adres = giriştenOku!(char[])("Adres?");
    auto yaş = giriştenOku!int("Yaşınız?");
}

İsim için !string, ve adres için !(char[]) kullandığıma dikkat edin. Her ikisi için de özelleştirme seçiliyor ve program char[] durumundaki .idup için derlenmiyor.

Tabii aslında kod tekrarını azaltmak için asıl özelleme şöyle:

T giriştenOku(T : string)(string soru)
{
    return giriştenOku!(char[])(soru).idup;
}

Yani string özellemesinde, genel tanımı char[] için kullanmayı umuyorum ama olmuyor.

Çözüm: std/conv.d dosyasının içine bakıyorum ve bu işi to!string için nasıl hallettiklerini öğreniyorum. Çok güzel değil... :) D'nin koşullu derleme olanaklarından yararlanıyorlar: static if...

Ben de şablonların koşullu derleme olanağına da başvuruyorum ve sonunda herşey halloluyor. Çalışan program şöyle:

import std.cstream;
 
T giriştenOku(T)(string soru)
{
    dout.writef(soru, ": ");
 
    T cevap;
    din.readf(&cevap);
 
    return cevap;
}
 
T giriştenOku(T : string)(string soru)
    if (is (T == string))          // <-- GEREKLİ
{
    return giriştenOku!(char[])(soru).idup;
}
 
void main()
{
    auto isim = giriştenOku!string("İsminiz?");
    auto adres = giriştenOku!(char[])("Adres?");
    auto yaş = giriştenOku!int("Yaşınız?");
}

Ama bu da çok saçma çünkü o özellemede şöyle bir anlam var: "bu, T'nin string olduğu durum için özellemedir; ama bunu T'nin string olduğu durumda göze al." :)

Bir bozukluk var. Haber gruplarında sordum; belki bilinen bir hatadır veya bir açıklaması vardır.

Ali
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Evet, galiba bilinen bir derleyicisi hatasıymış. Hatayı 'shared' için açmışlar ama benim karşılaştığım 'immutable' konusuyla aynı olmalı:

  http://d.puremagic.com/issues/show_bug.cgi?id=3750

Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-21, 15:22:55 (UTC -08:00)