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