Specialize a template parameter to implement 2 interfaces in D?
interface I1 { ... }
interface I2 { ... }
struct List(T) { ... }
How do I specialize my List to operate only on classes that implement both I1 and I2? One interface is easy:
struct List(T : I1)
Other languages. In C# it's:
struct List<T> where T : I1, I2
And in Java I'd say:
class List<T e开发者_StackOverflowxtends I1 & I2>
One catch: I don't want an if template constraint because I want reasonable auto-completion from a non-state-of-the-art IDEs. I think it'll be long before IDEs for D do things like reverse-engineering template constraints to deduce a list possible T's methods. And even if, that doesn't sound like cheap performance-wise.
If you don't want to constrain template by if statement, only way is this:
struct List(T : I1, U : I2 = T) { }
that means that you can instantiate List with one or two arguments, if you instantiate only with one - List!(C), then the U will be by default assigned value C, and checked if it implements I2. You can then ignore parameter U in the struct. The problem with this method is that you instantiate the List with two parameters - List!(C1, C2)...
Here is version with if constraint, which doesn't have this problem:
struct List2(T) if ( is(T : I1) && is(T : I2)) { }
There is no practical performance overhead in using if template constraint - or any compile time technique - if you are not calculating lot of data (like ct raytracer or look-up tables)
I would really suggest you to not limit your code to what the IDE supports - there sure will be many things that your IDE is not supporting well and you may find yourself having much less fun than using simple text editor with only sintax highlight, but with full potential of D.
In D2, you can use template constraints and the is
expression.
struct List(T)
if (is(T : I1) && is(T : I2))
{
...
}
Here, the is
expressions checks whether T
is implicitly convertible to I1
and I2
(which is only possible if T
implements them).
精彩评论