digitalmars.D.learn - mixin template bug with opBinary?
- Anthony Quizon (32/32) Jul 22 2022 Hello,
- Adam D Ruppe (30/31) Jul 22 2022 I think this is a bug. The compiler must not take well to this
- Anthony Quizon (2/10) Jul 22 2022 Thanks, this seems to do the trick.
- Steven Schveighoffer (9/51) Jul 22 2022 It's typing the AA differently, and therefore it doesn't fit. The type
- Paul Backus (3/10) Jul 22 2022 Looks like this bug:
Hello, I'm trying to create a mixin for quick binary operator overloads by passing in types with a corresponding associative array of strings to functions. However, the code I currently have: ``` module foo; mixin template opBi( A, A function(A, A)[string] f0, ) { static foreach (k, f; f0) { A opBinary(string op: k)(A r) { return f(this, r); } } } struct A { mixin opBi!( A, [ "+": (A a, A b) => a], ); } struct B { mixin opBi!( B, [ "+": (B a, B b) => a], ); } ``` Will not let me override operators on both struct A and B. I get: ``` foo.d(16): Error: mixin `foo.B.opBi!(B, ["+":function (B a, B b) pure nothrow nogc safe => a])` does not match template declaration `opBi(A, A function(A, A)[string] f0)` ``` Is this a bug or am I doing something wrong?
Jul 22 2022
On Friday, 22 July 2022 at 12:33:37 UTC, Anthony Quizon wrote:Is this a bug or am I doing something wrong?I think this is a bug. The compiler must not take well to this pattern, maybe the assoc array template argument, but idk. It looks like the first type used gets cached and reused even if it is supposed to change. I vaguely recall seeing this before.... but yeah smells buggy anyway. An alternative you might consider is dropping some of the type and using typeof(this): ``` module foo; mixin template opBi( alias f0 ) { static foreach (k, f; f0) { typeof(this) opBinary(string op: k)(typeof(this) r) { return f(this, r); } } } struct A { mixin opBi!( [ "+": (A a, A b) => a], ); } struct B { mixin opBi!( [ "+": (B a, B b) => a], ); } ``` That sidesteps the bug though it just trusts you pass the right type to `f0`.
Jul 22 2022
On Friday, 22 July 2022 at 12:56:44 UTC, Adam D Ruppe wrote:``` mixin template opBi( alias f0 ) { static foreach (k, f; f0) { typeof(this) opBinary(string op: k)(typeof(this) r) { return f(this, r); } } } ```Thanks, this seems to do the trick.
Jul 22 2022
On 7/22/22 8:33 AM, Anthony Quizon wrote:Hello, I'm trying to create a mixin for quick binary operator overloads by passing in types with a corresponding associative array of strings to functions. However, the code I currently have: ``` module foo; mixin template opBi( A, A function(A, A)[string] f0, ) { static foreach (k, f; f0) { A opBinary(string op: k)(A r) { return f(this, r); } } } struct A { mixin opBi!( A, [ "+": (A a, A b) => a], ); } struct B { mixin opBi!( B, [ "+": (B a, B b) => a], ); } ``` Will not let me override operators on both struct A and B. I get: ``` foo.d(16): Error: mixin `foo.B.opBi!(B, ["+":function (B a, B b) pure nothrow nogc safe => a])` does not match template declaration `opBi(A, A function(A, A)[string] f0)` ``` Is this a bug or am I doing something wrong?It's typing the AA differently, and therefore it doesn't fit. The type of the AA you are passing in is `T1[string]`, where it's expecting `T2[string]`, where: `T1` is `B function(B, B) pure nothrow nogc safe` `T2` is `B function(B, B)` I don't know if there's a better way to do this, other than use a further template parameter to match the function type passed in. -Steve
Jul 22 2022
On Friday, 22 July 2022 at 12:33:37 UTC, Anthony Quizon wrote:I get: ``` foo.d(16): Error: mixin `foo.B.opBi!(B, ["+":function (B a, B b) pure nothrow nogc safe => a])` does not match template declaration `opBi(A, A function(A, A)[string] f0)` ``` Is this a bug or am I doing something wrong?Looks like this bug: https://issues.dlang.org/show_bug.cgi?id=22540
Jul 22 2022