2010-08-20 78 views
2
interface I1 { ... } 
interface I2 { ... } 
struct List(T) { ... } 

如何專門化我的列表以僅對實現 I1和I2的類進行操作?一個接口很容易:專門設計一個模板參數來實現D中的2個接口?

struct List(T : I1) 

其他語言。在C#是:

struct List<T> where T : I1, I2 

而且在Java中我會說:

class List<T extends I1 & I2> 

一個陷阱:我不想要一個如果模板約束,因爲我想從非合理的自動完成最先進的IDE。我認爲D的IDE會做很多事情,比如反向工程模板約束來推導出列表可能的T方法。即使這聽起來不像廉價的性能。

+0

如果約束對於IDE來說不會比任何其他問題更難處理。 – BCS 2010-08-23 03:47:22

回答

3

如果你不想通過if語句來約束模板,唯一的辦法是這樣的:

struct List(T : I1, U : I2 = T) { } 

這意味着你可以實例列表有一個或兩個參數,如果你只用一個實例 - 列表!(C),那麼U將默認分配值C,並檢查它是否實現了I2。然後可以忽略結構中的參數U.使用這種方法的問題是,你實例有兩個參數列表 - 列表(C1,C2)...

下面是版本,如果約束,不存在這個問題:

struct List2(T) if (is(T : I1) && is(T : I2)) { } 

有一個在使用,如果模板約束沒有實際的性能開銷 - 或任何編譯時技術 - 如果你沒有計算大量數據(如CT光線跟蹤或查找表)

我真的建議你不要將您的IDE支持的代碼 - 肯定會有很多東西,IDE沒有很好的支持,你可能會發現自己有很多東西沒有使用簡單的文本編輯器,只有sintax突出顯示,但充分發揮D的潛力。

+0

默認參數的第一個例子很有趣,謝謝。 「聽起來不便宜」我並不是指運行時perf,但IDE(如果這樣聰明的人存在)提示我一個T的方法列表將不得不評估約束,遍歷表達式,認識到他們'既包含隱含的轉換要求,也包含它們之間的&& * *表示 - 大量工作。如果我選擇D作爲一個大項目,那麼我的假設IDE將無法跟上提供基本支持。所以我被困在簡單的文本編輯器中,閱讀DDocs而不是按Ctrl + Space,並且它沒有樂趣;) – 2010-08-21 10:57:13

+1

模板內部的靜態聲明(是(T == U))將停止濫用情況。 – BCS 2010-08-23 03:46:30

2

在D2中,您可以使用template constraintsis表達式。

struct List(T) 
    if (is(T : I1) && is(T : I2)) 
{ 
    ... 
} 

這裏,is表達式檢查是否T是隱式轉換爲I1I2(這是唯一可能的,如果T實現它們)。

+0

我知道;)但我明確表示,我不希望模板約束。 – 2010-08-21 10:26:47

+0

哎呀......對不起。這是我沒有仔細閱讀的結果。考慮到這個約束,我唯一能想到的就是定義'interface I3:I1,I2 {...}',然後將List限制爲I3。雖然不是太好。 – JRM 2010-08-21 17:53:56

+0

沒關係:)虛擬接口存在一個問題: 'class Item:I1,I2' 將被拒絕。擴大規模,你會在可能的接口的所有組合的數量結束傻瓜。 – 2010-08-22 11:20:34