On Wednesday, 3 August 2016 at 17:56:54 UTC, Jonathan M Davis wrote:
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[].

This is a good point, I admit. But still, isn't it the indexable objects task to define the opIndex method to take a particular index?

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.

Yes. I tested a struct, which has a Nullable value in it aliased to this and with an opCmp defined with respect to the Nullable value and it didn't worked, too. I find this strange, because if I already define, how the value should behave, if it is in the null state, I would assume, it should be able to index with it too...

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.

Yes. But this is just a compilation error... It says, well, there is a mistake in the code.

What I want is to achieve a constraint on my own type, which is at this time point defined just as
alias MyType = size_t;
but later on, this could maybe become a struct, and I still want to be able to handle it like an index.

The opIndex methods of the surrounding objects are already defined in terms of the MyType, so the problem of interacting does not play a big role. The question is how to describe the minimal requirement on the type itself...

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.

Yes... I can confirm this...
the last line of this code inside the main gives an error...
https://dpaste.dzfl.pl/043d1deb9073

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.

The code above, gives even a runtime error, which is much worse... It would be enough, I think, to assert, that MyType resolves to the particular set of types...
Which are these? Is it possible to write this kind of template?

Reply via email to