2012-01-06 115 views
2

在下面的代碼,我期望的輸出是爲什麼這些模板化功能不像虛擬功能?

B 
C 

但令人沮喪的足夠它是

A 
C 

有什麼我可以做,以使其行爲我期待的方式嗎?爲什麼這種行爲首先發生?
我辭職自己定義的stuff混入模板,並在每類中的覆蓋寫入,這解決了這個問題,但是是一個醜陋的黑客IMO相混合。

import std.stdio : writeln; 

class A { 
    void write() { 
     stuff(); 
    } 

    void stuff()() { 
     writeln("A"); 
    } 
} 


class B : A { 
    void stuff()() { 
     writeln("B"); 
    } 
} 

class C : A { 
    void write() { 
     stuff(); 
    } 

    void stuff()() { 
     writeln("C"); 
    } 

} 

void main (string[] args) { 
    B b = new B(); 
    b.write(); 
    C c = new C(); 
    c.write(); 
} 
+1

在'的東西()()',第一組括號將包含模板參數,在這種情況下,他們是空的,但它仍然計數。我也使用語法糖作爲'b.stuff()'而不是完整的'b.stuff!()()' – 2012-01-06 02:56:13

+0

(謝謝@Jean,我已經刪除了我原來的評論,因爲它是完全的我想我有一次關於D模板的新東西,但我已經忘了這一切!) – 2012-01-06 03:00:17

+0

好吧,通過添加空模板參數來使模板函數成爲模板的技巧可能不會出現在大多數人身上。它的主要用途是解決不允許使用非模板化函數重載模板化函數的問題。所以,從長遠來看,這可能不是一個特別有用的功能。 – 2012-01-06 03:05:25

回答

3

引述online documentation

模板不能被用於非靜態成員或虛擬 函數添加到類。

+0

啊謝謝,我沒看到那個。是否可以接受混合模板定義內部的東西,並將該模板混合到每個子類中以實現「虛擬性」?這是迄今爲止我找到的解決方案,但它並不適合我。 – 2012-01-06 02:54:24

+1

你不會得到這樣的「虛擬性」。這個實現完全取決於引用類型是什麼,而不是實際的對象類型。您可以使用模板將東西添加到基類。你不能重寫它。你可以有一個模板化函數知道所有的派生類,通過在運行時進行投射來確定實際的對象類型是什麼,然後使用特定的實現,但這很簡單。但最終「可以接受」的是由你和任何人處理你的代碼。 – 2012-01-06 03:02:34

+0

oops,我的意思是「虛擬性」的意思是模板函數使用字符串混合來修改類變量。如果它在基類中定義,並且子類有不同的類變量,那麼它將無法編譯這些語句。模板mixin解決了這個問題,因爲它的上下文現在是子類,它可以訪問這些新變量。你可以在這裏看到我的意思:http://codereview.stackexchange.com/q/7438/8619 – 2012-01-06 03:12:06