2010-08-20 80 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