On Monday, 1 August 2016 at 15:06:54 UTC, Jonathan M Davis wrote:

If you want a template constraint that checks that a type works with the index operator on a type, and you're not restricting it to something like size_t, then you're just going to have to check whether the expression is going to compile. Also, that is incompatible with random access ranges. Random access ranges are expected to work with size_t, and while isRandomAccessRange isn't currently quite that restrictive, it does check that r[1] compiles, so the index operator is going to have to accept integers at minimum. If you want a completely generic index operator, and you want a template constraint for it, you're pretty much going to have to test that it compiles. e.g.

auto fun(I, T)(I index, T obj)
    if(__traits(compiles, obj[index]))
{
    return obj[index];
}

or if you want a reusable template, you can do something like

template isIndexable(I, T)
{
    enum isIndexable = __traits(compiles, T.init[I.init]);
}

auto fun(I, T)(I index, T obj)
    if(isIndexable!(I, T))
{
    return obj[index];
}

Personally, I think that having code that accepts any type that can be indexable with any type isn't a particularly good idea, because odds are, it won't actually work, because those

different types will work quite differently (e.g. associative arrays are indexable with stuff other than size_t, but they're really not interchangeable with dynamic arrays or static arrays, which use size_t). And anything that wants to be interchangeable with a dynamic array or be usable as a random access range should be using size_t to index. But if you

This is exactly what my question is about. I don't think, that it doesn't make sense (and isn't a good idea) to index with an arbitrary type, too. So, how I can define/design a type, which is not an int/size_t, but has one to be able to index with it?

And if the __compiles trait is the way to go with... well then that's just how it is...

Reply via email to