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