Jump to page: 1 2
Thread overview
Should opIndex completely override alias this?
May 11, 2012
Trass3r
May 11, 2012
kenji hara
May 11, 2012
Mehrdad
May 11, 2012
kenji hara
May 11, 2012
David
May 11, 2012
Artur Skawina
May 11, 2012
Mehrdad
May 11, 2012
Mehrdad
May 11, 2012
Artur Skawina
May 11, 2012
Mehrdad
May 11, 2012
Artur Skawina
May 11, 2012
Artur Skawina
May 11, 2012
As soon as you define an opIndex, alias this isn't considered anymore.
Is this wanted behavior?

I'd have expected this to work:

	T[] data;
	T opIndex(size_t i, size_t j)
	{
		return data[i*numCols+j];
	}
	alias data this;

Then dynmap[3] would work by using data directly.
But: opIndex (ulong i, ulong j) is not callable using argument types (int)
May 11, 2012
2012/5/12 Trass3r <un@known.com>:
> As soon as you define an opIndex, alias this isn't considered anymore. Is this wanted behavior?
>
> I'd have expected this to work:
>
>        T[] data;
>        T opIndex(size_t i, size_t j)
>        {
>                return data[i*numCols+j];
>        }
>        alias data this;
>
> Then dynmap[3] would work by using data directly.
> But: opIndex (ulong i, ulong j) is not callable using argument types (int)

This is expected behavior.

'alias this' works as proper super type.

struct S { T[] data; alias data this; }

In this code, S behaves as it is derived from T[] .

Following to this view, the definition of opIndex in S overrides (and hides) T[]'s opIndex completely.

Kenji Hara
May 11, 2012
On Friday, 11 May 2012 at 17:19:28 UTC, kenji hara wrote:
> This is expected behavior.
>
> 'alias this' works as proper super type.
>
> struct S { T[] data; alias data this; }
>
> In this code, S behaves as it is derived from T[] .
>
> Following to this view, the definition of opIndex in S overrides (and
> hides) T[]'s opIndex completely.
>
> Kenji Hara

How do you overcome this, in the case where you don't know the data type of 'data' (so you don't know what the overloads might look like, maybe because it's a template)?
May 11, 2012
2012/5/12 Mehrdad <wfunction@hotmail.com>:
> On Friday, 11 May 2012 at 17:19:28 UTC, kenji hara wrote:
>>
>> This is expected behavior.
>>
>> 'alias this' works as proper super type.
>>
>> struct S { T[] data; alias data this; }
>>
>> In this code, S behaves as it is derived from T[] .
>>
>> Following to this view, the definition of opIndex in S overrides (and hides) T[]'s opIndex completely.
>>
>> Kenji Hara
>
>
> How do you overcome this, in the case where you don't know the data type of 'data' (so you don't know what the overloads might look like, maybe because it's a template)?

I'll add 'forwarding opIndex'.

struct S(T)
{
    T data;
    alias data this;

    int opIndex()(size_t i, size_t j)
    {
        return 100; // specialized opIndex
    }
    auto opIndex(A...)(A args) if (A.length != 2)
    {
        return data[args];  // forwarding
    }
}
void main()
{
    auto s = S!(int[])([1,2]);
    assert(s[1,2] == 100);
    assert(s[0] == 1);
    assert(s[1] == 2);
}
May 11, 2012
On 05/11/12 19:03, Trass3r wrote:
> As soon as you define an opIndex, alias this isn't considered anymore. Is this wanted behavior?
> 
> I'd have expected this to work:
> 
>     T[] data;
>     T opIndex(size_t i, size_t j)
>     {
>         return data[i*numCols+j];
>     }
>     alias data this;
> 
> Then dynmap[3] would work by using data directly.
> But: opIndex (ulong i, ulong j) is not callable using argument types (int)

That would mean a hidden opIndex overload (or more); not only can that make debugging harder, you then also would have to always make sure to override every opIndex present in 'data' if the indexing were to work differently in dynmap and T[]. Explicit forwarding is slightly more verbose, but much safer.

artur
May 11, 2012
On 05/11/12 19:22, Mehrdad wrote:
> On Friday, 11 May 2012 at 17:19:28 UTC, kenji hara wrote:
>> This is expected behavior.
>>
>> 'alias this' works as proper super type.
>>
>> struct S { T[] data; alias data this; }
>>
>> In this code, S behaves as it is derived from T[] .
>>
>> Following to this view, the definition of opIndex in S overrides (and hides) T[]'s opIndex completely.
>>
>> Kenji Hara
> 
> How do you overcome this, in the case where you don't know the data type of 'data' (so you don't know what the overloads might look like, maybe because it's a template)?

Not quite sure what you mean, but

    auto opIndex(A...)(A a) { return data[a]; }

artur
May 11, 2012
On Friday, 11 May 2012 at 17:37:11 UTC, Artur Skawina wrote:
> On 05/11/12 19:22, Mehrdad wrote:
>> On Friday, 11 May 2012 at 17:19:28 UTC, kenji hara wrote:
>>> This is expected behavior.
>>>
>>> 'alias this' works as proper super type.
>>>
>>> struct S { T[] data; alias data this; }
>>>
>>> In this code, S behaves as it is derived from T[] .
>>>
>>> Following to this view, the definition of opIndex in S overrides (and
>>> hides) T[]'s opIndex completely.
>>>
>>> Kenji Hara
>> 
>> How do you overcome this, in the case where you don't know the data type of 'data' (so you don't know what the overloads might look like, maybe because it's a template)?
>
> Not quite sure what you mean, but
>
>     auto opIndex(A...)(A a) { return data[a]; }
>
> artur

What if it's const/pure/@safe/whatever though? Or the parameters have some attributes?

(I guess this is a more general problem than opIndex specifically, though.)
May 11, 2012
> struct S(T)
> {
>      T data;
>      alias data this;
>
>      int opIndex()(size_t i, size_t j)
>      {
>          return 100; // specialized opIndex
>      }
>      auto opIndex(A...)(A args) if (A.length != 2)
>      {
>          return data[args];  // forwarding
>      }
> }
> void main()
> {
>      auto s = S!(int[])([1,2]);
>      assert(s[1,2] == 100);
>      assert(s[0] == 1);
>      assert(s[1] == 2);
> }

I want alias :/

struct S(T)
{
     T data;
     alias data this;

     int opIndex()(size_t i, size_t j)
     {
         return 100; // specialized opIndex
     }
     alias data.opIndex opIndex;
}
May 11, 2012
On Fri, 11 May 2012 13:47:13 -0400, Mehrdad <wfunction@hotmail.com> wrote:

> On Friday, 11 May 2012 at 17:37:11 UTC, Artur Skawina wrote:
>> On 05/11/12 19:22, Mehrdad wrote:
>>> On Friday, 11 May 2012 at 17:19:28 UTC, kenji hara wrote:
>>>> This is expected behavior.
>>>>
>>>> 'alias this' works as proper super type.
>>>>
>>>> struct S { T[] data; alias data this; }
>>>>
>>>> In this code, S behaves as it is derived from T[] .
>>>>
>>>> Following to this view, the definition of opIndex in S overrides (and
>>>> hides) T[]'s opIndex completely.
>>>>
>>>> Kenji Hara
>>>  How do you overcome this, in the case where you don't know the data type of 'data' (so you don't know what the overloads might look like, maybe because it's a template)?
>>
>> Not quite sure what you mean, but
>>
>>     auto opIndex(A...)(A a) { return data[a]; }
>>
>> artur
>
> What if it's const/pure/@safe/whatever though? Or the parameters have some attributes?
>
> (I guess this is a more general problem than opIndex specifically, though.)

D solves this by automatically adding pure @safe nothrow to a template function, wherever it is possible.

However, it doesn't do this for const or immutable.

-Steve
May 11, 2012
On Friday, 11 May 2012 at 18:09:13 UTC, Steven Schveighoffer wrote:
> On Fri, 11 May 2012 13:47:13 -0400, Mehrdad <wfunction@hotmail.com> wrote:
>
>> On Friday, 11 May 2012 at 17:37:11 UTC, Artur Skawina wrote:
>>> On 05/11/12 19:22, Mehrdad wrote:
>>>> On Friday, 11 May 2012 at 17:19:28 UTC, kenji hara wrote:
>>>>> This is expected behavior.
>>>>>
>>>>> 'alias this' works as proper super type.
>>>>>
>>>>> struct S { T[] data; alias data this; }
>>>>>
>>>>> In this code, S behaves as it is derived from T[] .
>>>>>
>>>>> Following to this view, the definition of opIndex in S overrides (and
>>>>> hides) T[]'s opIndex completely.
>>>>>
>>>>> Kenji Hara
>>>> How do you overcome this, in the case where you don't know the data type of 'data' (so you don't know what the overloads might look like, maybe because it's a template)?
>>>
>>> Not quite sure what you mean, but
>>>
>>>    auto opIndex(A...)(A a) { return data[a]; }
>>>
>>> artur
>>
>> What if it's const/pure/@safe/whatever though? Or the parameters have some attributes?
>>
>> (I guess this is a more general problem than opIndex specifically, though.)
>
> D solves this by automatically adding pure @safe nothrow to a template function, wherever it is possible.
>
> However, it doesn't do this for const or immutable.
>
> -Steve

Yeah I remember that was a relatively recent fix, but there's still the issue of perfect forwarding that isn't possible in D:
http://stackoverflow.com/questions/7948865
« First   ‹ Prev
1 2