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