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.

Reply via email to