C#'s greatest mistakes
Jonathan M Davis
jmdavisProg at gmx.com
Sat Nov 27 17:06:32 PST 2010
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<SeeWebsiteForEmail at erdani.org>:
> >>>> 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
More information about the Digitalmars-d
mailing list