On Saturday 27 November 2010 16:18:00 BLS wrote: > On 28/11/2010 00:19, Jonathan M Davis wrote: > > On Saturday 27 November 2010 14:59:09 BLS wrote: > >> On 27/11/2010 16:59, Torarin wrote: > >>> 2010/11/27 Andrei Alexandrescu<[email protected]>: > >>>> We use template constraints for that kind of stuff. > >>>> > >>>> Andrei > >>> > >>> Yes, and that's great, but is there a way to check whether a template > >>> argument matches a defined interface? > >> > >> I could not resist.. > >> We should have Implements! > >> > >> Luca has done some work on it.. but it does not compile anymore. However > >> I think the intension is clear. > >> http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars. > >> D&a rticle_id=101673 > > > > If you're checking whether it implements an interface, then : should work > > just like it does with classes. If you're checking whether it has the > > same functions that an interface requires, then you're not really using > > interfaces correctly. structs don't implement interfaces. Classes do > > that. So, either make it a class, or don't use interfaces. If you want > > to verify that a struct has particular functions needed for the template > > function in question, then just check whether calling them compiles ( > > e.g. __traits(compiles, foo.bar()) ). If you have a set of functions > > that are expected to be there (for instance, to verify that the given > > type is a certain type of range), then just create template which checks > > for each of the functions that are supposed to be there and use the > > template ( e.g. isForwardRange!T ). Interfaces and structs don't have > > anything to do with each other. > > > > - Jonathan M Davis > > Thanks for taking the time to explain. I've copypasted. > However, > Given that dCollections enable me to change the underlaying algorithm > (say I can replace the default RBTree with SkipList) In order to so that > I have to fulfil some requirements. And now, I guess that is what I am > talking about. I want a guarantee that my skiplist implementation > fulfills the cursor (a structure) requirements. > > So now what is wrong with the contract from dCollections I am asking > for. Please note that dCollections implements cursors as well as ranges.
Interfaces are class-based. Only classes can implement them. It makes no sense to use an interface with structs, because you can't do it. If you're using interfaces with a template, then you simply verify that the type implements the interface in question. You should be able to use : exactly in the same manner that you'd use it to check that a class is a particular type or is derived from a that type. On the other hand, if you're using structs, then the only way that you're going to be able to interchange them based on an API is with templates. A struct cannot implement an interface. So, it makes no sense to talk about a struct implementing one. If you want to ensure that a type that is used to instantiate a template has a certain API, then you verify that in the template constraint, and the way to do that in a manner which is reusable is to use a template which verifies that the type has every function that it's supposed to have. You then use that template in the template constraint. The range templates such as IsForwardRange!() and isInputRang!e() are prime examples of that. You could theoretically create a template which verified that a struct had the same functions that an interface required for a class to implement it, but since a struct can't implement it, it's just confusing and unnecessary to add a useless interface into the mix. The struct can't implement it. And if you you're using a class instead of struct, then the template should verify that the type implements the interface. And if it's templated simply on the type, then you probably don't even need a template - just use the interface itself directly. I don't know exactly what DCollections does. But it's using the language to do whatever it's doing. So, if it's an interface that you need, you have to be using classes, and you can have template constraints verify that the type implements the template. structs never will, so they'll fail the constraint. If, on the other hand, you need to match a particular API - no interfaces involved - then it's going to be a template, and then any template constraints need to verify that whatever functions the template requires are present on the type. No interfaces are involved. Really, if you're trying to have a struct implement an interface (as opposed to an API), then you're misunderstanding how interfaces work. - Jonathan M Davis
