where to find Implements!

Jonathan M Davis jmdavisProg at gmx.com
Wed Sep 29 15:40:06 PDT 2010


On Wednesday, September 29, 2010 13:58:05 BLS wrote:
> On 29/09/2010 22:28, Jonathan M Davis wrote:
> > Look in
> > std.range for the whole list, but isRandomAccesRange() handles random
> > access ranges. Since there is no interface for ranges, you can't check
> > generically whether a particular type correctly implements a particular
> > range type - e.g is(mystruct : RandomAccessRange) or
> > implements!(RandomAccessRange, mystrucT).
> 
> Thanks ! This is already something. (not exactly what I am
> looking/hoping for)
> 
> why we don't have /struct A implements IA {}/ by the way.

Interfaces are reference types and involve the type's virtual table. structs are 
value types (though they can have reference semantics if they contain reference 
types and don't define a postblit constructor to do a deep copy), and I don't 
believe that they have a vtable. They can't have sub structs, so they're not 
polymorphic and so don't have virtual functions, so there's no need. With an 
interface, you're dealing with virtual functions, so you'd need a vtable. But 
the simple fact that passing around an interface would mean passing around a 
reference type means that it isn't going to work with structs.

I believe that Andrei has said that it would be theoretically possible to make 
structs able to implement interfaces, but it would involve giving them virtual 
tables explicitly so that they could have interfaces (which would make structs 
less efficient in general, since using a vtable makes function calls slower, 
albeit negligibly) and making it so that you could have reference to a struct 
when that reference was an interface that the struct implemented. Both would be 
significant changes and could harm the overall performance of using structs.

Phobos doesn't use interfaces. It uses duck typing. Any type - be it a struct or 
a class - which has the appropriate methods will work for any function that 
requires a particular API on the type or types that it's dealing with. There's 
no need to have any interfaces. They just work if they have the correct API and 
don't work if they don't. The isRandomAccessRange() template and its friends are 
used in template constraints to improve the error messages you get when a type 
doesn't have the correct API, but they aren't strictly-speaking necessary.

If interfaces were used, it would mean less efficient code (since you'd have to 
use classes) and it would be far less flexible. As it is, any type - struct or 
class - with the appropriate API will work.

- Jonathan M Davis


More information about the Digitalmars-d mailing list