| Thread overview | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 11, 2012 Should opIndex completely override alias this? | ||||
|---|---|---|---|---|
| ||||
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 Re: Should opIndex completely override alias this? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Trass3r | 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 Re: Should opIndex completely override alias this? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to kenji hara | 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 Re: Should opIndex completely override alias this? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Mehrdad | 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 Re: Should opIndex completely override alias this? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Trass3r | 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 Re: Should opIndex completely override alias this? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Mehrdad | 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 Re: Should opIndex completely override alias this? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Artur Skawina | 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 Re: Should opIndex completely override alias this? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to kenji hara | > 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 Re: Should opIndex completely override alias this? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Mehrdad | 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 Re: Should opIndex completely override alias this? | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply