Indexing with an arbitrary type

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Aug 3 10:56:54 PDT 2016


On Wednesday, August 03, 2016 16:42:18 Alex via Digitalmars-d-learn wrote:
> On Wednesday, 3 August 2016 at 14:46:25 UTC, Alex wrote:
> > On Wednesday, 3 August 2016 at 14:23:59 UTC, Jonathan M Davis
> > wrote:
> >
> > But it should.
> >
> > Just found this:
> > https://www.sgi.com/tech/stl/StrictWeakOrdering.html
> > which should be fulfilled by a type, which can be used as a
> > key. So, in my opinion, the property "being a key" is a matter
> > of an abstract definition and should have nothing to do with
> > objects which I want to index with it.
> >
> > Sure, the object which I want to index, has to define an
> > opIndex method, which can receive the key-thing, but this is
> > already the next step.
>
> So, I think this is the answer to my question:
> http://stackoverflow.com/questions/27282568/d-template-constraint-to-show-wh
> ether-a-given-type-is-comparable

int is comparable, but it's not going to index float[string]. Only a string
is going to do that. Similarly, long is comparable, but on a 32-bit system,
it won't index int[], because it's larger than size_t, which is the actual
index type for int[].

If all that your code cares about is that type T is comparable, then sure,
test that it's comparable. But if it's going to pass a value of type T to
the index operator of type U, then T's index operator needs to accept type
U. And a type like SysTime from std.datetime is comparable, but it sure
isn't going to work as an index for int[].

And being comparable isn't enough to guarantee that T is going to work.
In fact, there isn't even a guarantee that U's opIndex even takes a type
that's comparable. Maybe it's a weird socket type that use opIndex to
connect to a particular IP address rather than having a properly named
function for that, and it takes an Address object that isn't comparable.
Yes, that would be weird and likely bad design, but there's nothing about
opIndex that prevents it. So, testing for whether U was comparable wouldn't
necessarily tell you whether it could be used to index a type.

But even if everyone restricts themselves to using opIndex in sane ways, and
all index types are comparable, not all types take the same index types. So,
if you just test that the index type is comparable without testing it
against the type that it's actually going to index, then your template
constraint will let through types that won't be compatible and will result
in a compilation error.

Maybe I don't understand enough about what you're trying to do and am not
giving the best advice as a result, but if you have a function that takes a
two arguments where one is supposed to be an index, and the other is
supposed to be an object to be indexed, then the only template constraint
that will prevent types getting through which won't compile when the code
actually uses the index operator is to test that the object to be indexed
can be indexed by the index object. Testing that the index type is
comparable is completely insufficient. It will work with a particular set of
types, but it will not work with all indexable types, and if a types that
don't work together are passed to that function, then you will get a
compilation error inside of the function instead of at the template
constraint catching it.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list