| Thread overview | |||||||||
|---|---|---|---|---|---|---|---|---|---|
|
September 19, 2015 Templated opIndex? | ||||
|---|---|---|---|---|
| ||||
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?
| ||||
September 19, 2015 Re: Templated opIndex? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to OlaOst | 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];
}
| |||
September 19, 2015 Re: Templated opIndex? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to John Colvin | 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:
>> [...]
>
> 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:
>
> [...]
Thanks, option 1 is what I'm using today. It's a little annoying though, since templated OpIndexAssign works perfectly.
| |||
September 19, 2015 Re: Templated opIndex? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to OlaOst | 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?
| |||
September 19, 2015 Re: Templated opIndex? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ola Fosheim Grøstad | And this:
class TestInt: Test {
alias opIndex = super.opIndex!int;
}
class TestString: Test {
alias opIndex = super.opIndex!string;
}
| |||
September 19, 2015 Re: Templated opIndex? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Ola Fosheim Grøstad | 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]);
}
| |||
September 20, 2015 Re: Templated opIndex? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to OlaOst | On 09/19/2015 02:33 AM, 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?
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
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply