Indexing with an arbitrary type

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Aug 1 06:52:56 PDT 2016


On Monday, August 01, 2016 11:06:54 Alex via Digitalmars-d-learn wrote:
> Hi everybody,
> I have a question and a half on templates and ranges, this time.
> Say, I have two functions:
>
> auto f1(T, S)(T t, S s) if(isIntegral!T && isRandomAccessRange!S)
> {
>      return s[t];
> }
>
> auto f2(T, S)(T t, RandomAccessFinite!S raf) if(isIntegral!T)
> {
>      return raf[t];
> }
>
> and a
> class myClass : RandomAccessFinite!ubyte {...}
> which implements all the methods needed by the RandomAccessFinite
> interface.
>
> then, I could use this in my main by just
>
> void main()
> {
>      myClass mC = new myClass();
>      writeln(f2(1, mC));
>      writeln(f1(1, mC));
>
>      ubyte[] arr = [0, 42, 2, 3, 4];
>      writeln(f1(1, arr));
>      //writeln(f2(1, arr)); //this fails and is the first part of
> the question.
> }
>
> so, the first question is, why the method using the
> RandomAccessFinite interface fails on using an array? Did I miss
> a method, which is not supported by an array?

An array does not implement RandomAccessFinite, which is an interface that
you created. So, a function that takes a RandomAccessFinite is not going to
accept an array. A dynamic array will match isRandomAccessRange, but that
has nothing to do with interfaces.

> But the main question is about the other part, about the
> constraint to the first parameter to my functions.
> It seems strange to me to use "isIntegral" here, as this is some
> kind of unrelated for something used as an index.
> Is there anything more appropriate to check? What kind of
> interface/trait has an index to fulfill?

What's strange? If you want to accept any integer type, then isIntegral!T
would do it. A _better_ thing to do would be to make it so that it's just
size_t and not templatize the type, since indices really should be size_t
normally (and if the system is 32-bit, then isIntegral!T will accept long
and ulong, whereas size_t is uint, and if you pass a long, you'll get a
compilation error for arrays, since they take size_t for indexing; it won't
matter for 64-bit though, since size_t is ulong there). So,

auto f1(R)(size_t index, R range)
    if(isRandomAccessRange!R)
{
    return range[index];
}

would be better, but aside from the 32-bit issues, isIntegral will work.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list