Indexing with an arbitrary type

Alex via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed Aug 3 07:46:25 PDT 2016


On Wednesday, 3 August 2016 at 14:23:59 UTC, Jonathan M Davis 
wrote:
> On Wednesday, August 03, 2016 09:21:13 Alex via 
> Digitalmars-d-learn wrote:
>> On Monday, 1 August 2016 at 16:09:50 UTC, Alex wrote:
>> > On Monday, 1 August 2016 at 15:51:58 UTC, Jonathan M Davis
>> > wrote:
>> > template isIndexable(I, T)
>> > {
>> >
>> >     enum isIndexable = __traits(compiles, T.init[I.init]);
>> >
>> > }
>>
>> As a last question afterwards:
>> Is it possible to create such an isIndexable template without
>> templating over the type T?
>> something like
>>
>> template isIndexable(I)
>> {
>>      enum isIndexable = __traits(compiles, ???[I.init]);
>> }
>>
>> sure, I could use
>>
>> __traits(compiles, (int[]).init[I.init])
>>
>> but is this the intended way to go?
>
> __traits(compiles, ...) is testing whether the code in question 
> compiles. What you need to test is whether the object is 
> indexable by the other, and that would mean needing both the 
> type being indexed and the type which is the index. Just 
> because one particular type is indexable by whatever the index 
> type is doesn't mean that another will be. For instance, int[] 
> is only going to be indexable by size_t and anything that 
> implicitly converts to size_t. Testing whether int[] is 
> indexable with size_t isn't going to say anything about whether 
> int[string] is indexable with size_t. If you want to test that 
> int[string] is indexable with size_t, you'll need to actually 
> test it with size_t, not int[] - the same goes for any other 
> combinaton of object to index and object that is the index. If 
> you're just typing out the whole thing every time, then you can 
> do stuff like
>
> auto foo(I, T)(I index, T obj)
>     if(__traits(compiles, obj[index]))
> {
>     ...
> }
>
> because you have actual objects to deal with, whereas with a 
> template written to encapsulate that test, you only have the 
> types. The init property is just an easy way to get at an 
> object of the type without declaring it or worrying about how 
> one is constructed. But to do the same test as that example 
> with a separate template, you're going to need both types. e.g.
>
> template isIndexable(I, T)
> {
>     enum isIndexable = __traits(compiles, T.init[I.init]);
> }
>
> If you don't have both, you're not doing the same test, and 
> it's impossible to test that one type is indexable by another 
> without using both types in the test. To only have one of the 
> two types in a test would be like trying t to test whether a 
> function can be called on a particular type while only having 
> the function in the test and not the type. It doesn't work.
>
> - Jonathan M Davis

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.


More information about the Digitalmars-d-learn mailing list