digitalmars.D - Should opIndex completely override alias this?
- Trass3r (11/11) May 11 2012 As soon as you define an opIndex, alias this isn't considered anymore.
- kenji hara (9/20) May 11 2012 )
- Mehrdad (4/12) May 11 2012 How do you overcome this, in the case where you don't know the
- kenji hara (22/39) May 11 2012 I'll add 'forwarding opIndex'.
- David (11/31) May 11 2012 I want alias :/
- Artur Skawina (4/19) May 11 2012 Not quite sure what you mean, but
- Mehrdad (5/27) May 11 2012 What if it's const/pure/@safe/whatever though? Or the parameters
- Steven Schveighoffer (5/33) May 11 2012 D solves this by automatically adding pure @safe nothrow to a template
- Mehrdad (5/42) May 11 2012 Yeah I remember that was a relatively recent fix, but there's
- Artur Skawina (8/31) May 11 2012 Since it is a function template the attributes are inferred, in this cas...
- Mehrdad (2/5) May 11 2012 Among other things, 'scope' gets messed up.
- Artur Skawina (9/14) May 11 2012 How? By making the forwarder not callable w/ a scoped argument, when the
- Artur Skawina (6/20) May 11 2012 That would mean a hidden opIndex overload (or more); not only can that m...
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: =A0 =A0 =A0 =A0T[] data; =A0 =A0 =A0 =A0T opIndex(size_t i, size_t j) =A0 =A0 =A0 =A0{ =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return data[i*numCols+j]; =A0 =A0 =A0 =A0} =A0 =A0 =A0 =A0alias 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 HaraHow 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: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); }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 HaraHow 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
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 05/11/12 19:22, Mehrdad wrote:On Friday, 11 May 2012 at 17:19:28 UTC, kenji hara wrote:Not quite sure what you mean, but auto opIndex(A...)(A a) { return data[a]; } arturThis 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 HaraHow 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
On Friday, 11 May 2012 at 17:37:11 UTC, Artur Skawina wrote:On 05/11/12 19:22, Mehrdad wrote: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.)On Friday, 11 May 2012 at 17:19:28 UTC, kenji hara wrote:Not quite sure what you mean, but auto opIndex(A...)(A a) { return data[a]; } arturThis 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 HaraHow 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
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: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. -SteveOn 05/11/12 19:22, Mehrdad wrote: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.)On Friday, 11 May 2012 at 17:19:28 UTC, kenji hara wrote:Not quite sure what you mean, but auto opIndex(A...)(A a) { return data[a]; } arturThis 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 HaraHow 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
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: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/7948865On Friday, 11 May 2012 at 17:37:11 UTC, Artur Skawina wrote: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. -SteveOn 05/11/12 19:22, Mehrdad wrote: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.)On Friday, 11 May 2012 at 17:19:28 UTC, kenji hara wrote:Not quite sure what you mean, but auto opIndex(A...)(A a) { return data[a]; } arturThis 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 HaraHow 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
On 05/11/12 19:47, Mehrdad wrote:On Friday, 11 May 2012 at 17:37:11 UTC, Artur Skawina wrote:Since it is a function template the attributes are inferred, in this case from data's opIndex, if any. The arguments are forwarded as-is, ie data's opIndex has to deal with them. The return type could be 'auto ref' too, then returning by reference would also magically work, but this is not always desirable, as it could leak private references; making return-by-ref explicit is probably safer in cases like this one. arturOn 05/11/12 19:22, Mehrdad wrote:What if it's const/pure/ safe/whatever though? Or the parameters have some attributes?On Friday, 11 May 2012 at 17:19:28 UTC, kenji hara wrote:Not quite sure what you mean, but auto opIndex(A...)(A a) { return data[a]; }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 HaraHow 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
On Friday, 11 May 2012 at 18:32:12 UTC, Artur Skawina wrote:Since it is a function template the attributes are inferred, in this case from data's opIndex, if any. The arguments are forwarded as-is, ie data's opIndex has to deal with them.Among other things, 'scope' gets messed up.
May 11 2012
On 05/11/12 20:40, Mehrdad wrote:On Friday, 11 May 2012 at 18:32:12 UTC, Artur Skawina wrote:How? By making the forwarder not callable w/ a scoped argument, when the target function would be? It isn't a problem for operator overloading, as the signature(s) are known. But in general, scope-inference would be needed. Which has similar problems as 'uniq', for non-trivial function bodies. Yes, things aren't perfect; eg 'this' attributes/classes like shared or const also need explicit handling (recent frontend changes apparently improved the situation a bit). arturSince it is a function template the attributes are inferred, in this case from data's opIndex, if any. The arguments are forwarded as-is, ie data's opIndex has to deal with them.Among other things, 'scope' gets messed up.
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