Forum: D Programlama Dili RSS
Template olanakları hakkında
Avatar
zekeriyadurmus #1
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Template olanakları hakkında
void x(T : T[])(T[] arr){
}
 
int main(string[] argv){
    x("qwe");//çalışmıyor
    x!string("qwe");//çalışıyor
}
Şöyle bir şey yapmaya çalıştım ama beceremedim bir türlü. Niyetim o fonksiyonun dizileri almasını sağlamak ama ille de !string şeklinde belirtmek gerekiyor. Çoğu zaman otomatik algılarken burada algılayamıyor. !string deyimini kaldırmak için ne yapmalıyız?

Not: Başlığa bir şey bulamadım. Ali hocam başlık için uygun bir şey varsa değiştirebilirsiniz :)

Zekeriya
Bilgi meraktan gelir...
Avatar
zekeriyadurmus #2
Kullanıcı başlığı: Talha Zekeriya Durmuş
Üye Eki 2012 tarihinden beri · 701 mesaj · Konum: Samsun/Türkiye
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Şöyle bir şeyler yazdım

import std.stdio;
import std.algorithm;
import std.c.stdlib;
import core.memory;
import std.conv;
 
struct MemArea{
     /// Heap
    __gshared void* freemem;
    __gshared size_t pos;
    __gshared size_t size = 1024 * 1024 * 10; /// Allocate 10 mb heap
    static this(){
        freemem = GC.malloc(size, GC.BlkAttr.NO_SCAN);
        assert(freemem !is null);
    }
}
 
struct Arr(T : T[]){
    alias arr this;
    @disable this();
    @disable this(this);
    ~this(){
        refcount--;
        if(refcount == 0 ){
            writeln("sonlandır");
        }
    }
    union{
        T[] arr;
        private struct{
            uint length;
            T* ptr;
        }
    }
    uint refcount;
 
    this(T[] arr){
        ptr = cast(T*) (MemArea.freemem + MemArea.pos);
        length = arr.length;
        (MemArea.freemem + MemArea.pos)[0..arr.length * T.sizeof] = cast(void[]) arr[];
    }
    new(size_t length){
        auto ret = MemArea.freemem + MemArea.pos;
        MemArea.pos += length;
        return ret;
    }
    string toString() const{
        return to!string(arr);
    }
}
void main(string[] argv){
    try{
        {
            auto str = new Arr!(int[])([12,12]);
            assert(*str == [12,12]);
            assert(cast(void*) str == MemArea.freemem);
            assert(cast(void*) str.ptr == MemArea.freemem + (*str).sizeof);
            writeln(cast(int[]) *str);
        }
        {
            auto str = new Arr!string("Test");
            writeln(str.toString());
        }
    }catch(Throwable x){
        writeln(x);
    }
    //while(1){}
}

Zekeriya
Bilgi meraktan gelir...
acehreli (Moderatör) #3
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ı
Yanıtlanan mesaj #1
zekeriyadurmus:
void x(T : T[])(T[] arr){
}

Öyle yazınca sanki tanımda bir sonsuzluk var: "sana T dilimi vereceğim; öyle ki, her elemanı bir T[] olsun." Yani T dilimi dilimi dilimi... gibi...

Bunu parametreye bakarak görebiliriz: string verdiğimizde ilk bakışta T'nin immutable(char) olması gerekiyor gibi görünüyor ama şablon parametre listesine uymuyor çünkü immutable(char) kendisi bir immutable(char)[] değil.

Yukarıdaki açıklamaya en uygun çözüm şu:
void x(T)(T[] arr){
}
O durumda T'nin türü immutable(char) olarak çıkarsanır.

Başka çözüm, işlev parametresini T olarak bırakmak ama şablon parametresinde onun başka bir türün dilimi olduğunu söylemek:
void x(T : U[], U)(T arr){
}
Anlamı: "Sana bir tür vereceğiz; öyle ki, U[] dilimine uysun; U bir türdür."

Veya, şablon kısıtlaması ile:
import std.traits;
 
void x(T)(T arr)
    if (isSomeString!T)
{}
Veya, yine baştaki gibi düşünüp işlev parametresini dilim gibi yazarsak:
import std.traits;
 
void x(T)(T[] arr)
    if (isSomeChar!T)
{}
Ama tabii önceki örneklerden bazılarında da olduğu gibi, bu son örnekte T bir karakter türü olduğundan bu sefer senin son çağrı derlenmez:
    x!string("qwe");    // derleme hatası 
çünkü T bir string değil, bir string elemanı.

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-18, 00:36:18 (UTC -08:00)