digitalmars.D.learn - Templated opIndex?
- OlaOst (26/26) Sep 19 2015 Here is a class with a templated opIndex method, and an attempt
- John Colvin (30/56) Sep 19 2015 2 approaches:
- OlaOst (3/9) Sep 19 2015 Thanks, option 1 is what I'm using today. It's a little annoying
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (3/6) Sep 19 2015 test.opIndex!int(0)
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (7/7) Sep 19 2015 And this:
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (13/13) Sep 19 2015 And this?
- =?UTF-8?Q?Ali_=c3=87ehreli?= (35/58) Sep 19 2015 Templated opIndex is used for multi-dimensional array indexing. The
Here is a class with a templated opIndex method, and an attempt to use it: class Test { int[] numbers = [1, 2, 3]; string[] texts = ["a", "b", "c"]; Type opIndex(Type)(int index) { static if (is(Type == int)) return numbers[index]; static if (is(Type == string)) return texts[index]; } } void main() { auto test = new Test(); auto number = test[0]!int; // does not compile, syntax error auto number = test!int[0]; // does not compile, syntax error int number = test[0]; // does not compile, cannot deduce type } So it is possible to define a templated opIndex method in a class, but is it possible to use it? If not, should it be allowed to create templated opIndex methods?
Sep 19 2015
On Saturday, 19 September 2015 at 09:33:02 UTC, OlaOst wrote:Here is a class with a templated opIndex method, and an attempt to use it: class Test { int[] numbers = [1, 2, 3]; string[] texts = ["a", "b", "c"]; Type opIndex(Type)(int index) { static if (is(Type == int)) return numbers[index]; static if (is(Type == string)) return texts[index]; } } void main() { auto test = new Test(); auto number = test[0]!int; // does not compile, syntax error auto number = test!int[0]; // does not compile, syntax error int number = test[0]; // does not compile, cannot deduce type } So it is possible to define a templated opIndex method in a class, but is it possible to use it? If not, should it be allowed to create templated opIndex methods?2 approaches: 1) use a function instead. E.g. test.get!int(0); isn't too bad 2) If you really want to use [], do something like this: class Test { int[] numbers = [1, 2, 3]; string[] texts = ["a", "b", "c"]; private struct Idx(T) { T data; auto opIndex(size_t index) { return data[index]; } } auto idx(Type)() property { static if (is(Type == int)) return Idx!(int[])(numbers); static if (is(Type == string)) return Idx!(string[])(texts); } } void main() { auto test = new Test(); auto number = test.idx!int[0]; auto text = test.idx!string[0]; }
Sep 19 2015
On Saturday, 19 September 2015 at 10:16:58 UTC, John Colvin wrote:On Saturday, 19 September 2015 at 09:33:02 UTC, OlaOst wrote:Thanks, option 1 is what I'm using today. It's a little annoying though, since templated OpIndexAssign works perfectly.[...]2 approaches: 1) use a function instead. E.g. test.get!int(0); isn't too bad 2) If you really want to use [], do something like this: [...]
Sep 19 2015
On Saturday, 19 September 2015 at 09:33:02 UTC, OlaOst wrote:So it is possible to define a templated opIndex method in a class, but is it possible to use it? If not, should it be allowed to create templated opIndex methods?test.opIndex!int(0) works?
Sep 19 2015
And this: class TestInt: Test { alias opIndex = super.opIndex!int; } class TestString: Test { alias opIndex = super.opIndex!string; }
Sep 19 2015
And this? auto ref qua(T)(Test t){ struct wrap { Test t; T opIndex(int i){ return t.opIndex!T(i); } } return wrap(t); } void main() { auto test = new Test(); writeln(test.qua!string[0], test.qua!int[0]); }
Sep 19 2015
On 09/19/2015 02:33 AM, OlaOst wrote:Here is a class with a templated opIndex method, and an attempt touse it:class Test { int[] numbers = [1, 2, 3]; string[] texts = ["a", "b", "c"]; Type opIndex(Type)(int index) { static if (is(Type == int)) return numbers[index]; static if (is(Type == string)) return texts[index]; } } void main() { auto test = new Test(); auto number = test[0]!int; // does not compile, syntax error auto number = test!int[0]; // does not compile, syntax error int number = test[0]; // does not compile, cannot deduce type } So it is possible to define a templated opIndex method in a class, but is it possible to use it? If not, should it be allowed to create templated opIndex methods?Templated opIndex is used for multi-dimensional array indexing. The template arguments define the range of elements: http://ddili.org/ders/d.en/templates_more.html#ix_templates_more.opIndex%20template And the spec: http://dlang.org/operatoroverloading.html#array-ops I would prefer the following: test.numbers[0]; test.texts[0]; but in addition to other solutions, here is another experiment: struct indexFor(T) { size_t idx; } class Test { int[] numbers = [1, 2, 3]; string[] texts = ["a", "b", "c"]; T opIndex(T)(indexFor!T index) { static if (is(T == int)) return numbers[index.idx]; static if (is(T == string)) return texts[index.idx]; assert(false); } } void main() { auto test = new Test(); auto number = test[indexFor!int(0)]; } Ali
Sep 19 2015