2010-10-05 125 views
5

我有一個班級,我正在實施的範圍。我想以phobos庫的方式實現這些功能,即在主類之外。非會員範圍功能

void popBack(T)(ref T[] a) if (!is(Unqual!T == char) && !is(Unqual!T == wchar)) 
{ 
    assert(a.length); 
    a = a[0 .. $ - 1]; 
} 

這裏是我的版本:

void popFront(T)(ref PersistentList!(T) a) 
{ 
    a = a.next(); 
} 

當我嘗試編譯這段代碼有forech,我得到:

Error 1 Error: no property 'popFront' for type 'stmd.PersistentList!(int).PersistentList' main.d 

我會會員代碼移動到主類,但由於我正在修改輸入「ref」值,我不能使用popFront()我真的需要popFront(ref a)。

我在做什麼錯?

回答

4

你要做什麼取決於D社區調用統一函數調用語法。這是使用與成員函數相同的語法來調用非成員函數的能力。這已經在數組中實現了很長時間,並且對於採用它的程度還有一些爭論。已經決定應該爲所有類型實現它,但編譯器實現者Walter Bright尚未開始這樣做,因爲他在64位支持上一直在狂熱地工作。

統一函數調用語法在Andrei Alexandrescu的書「The D Programming Language」中描述,它被認爲是D2的權威指南。目前缺乏實施被認爲是一個錯誤。這應該在幾個版本中修復。

+0

感謝您的評論。我的類是不可變的,所以我實際上在類中本身不能有一個popFront成員。但我確實創建了一個「PersistentListRange」子類,所以我可以做foreach(i; lst.range),並且工作得很好。 – 2010-10-06 12:58:05

3

Phobos僅在數組的struct/class之外實現範圍函數。數組允許你在它們上調用函數,就像它們是成員函數一樣。所以,如果你有這樣的功能:

int func(int[] arr) 
{ 
    return arr[0]; 
} 

你可以調用它像這樣

auto arr = [1, 2, 3]; 
auto val = arr.func(); 

代替

auto val = func(arr); 

如果能夠做到這一點與所有類型的被稱爲通用函數調用語法,但這在D中目前還不合法,儘管它看起來可能會被添加。

除非您希望與其他範圍類型共享該實現,否則實際上沒有理由在範圍類型外聲明您的範圍函數,因爲內部實現必須處理容器類型如何維護其數據。所以,你可能只是讓它們成爲你的範圍類型的一部分。這就是Phobos在所有情況下都會做的事情,除了數組之外,顯然不能將它們作爲其類型的一部分,並且必須使用它們的功能來調用它們,就好像它們是成員函數一樣才能工作。