On Tuesday, 9 September 2025 at 01:24:59 UTC, monkyyy wrote:

```d
import std;
struct Vector(int N,T,string fields){
        static foreach(I;0..N){
                mixin("T "~fields[I]~";");
        }
auto opDispatch(string __s__)(){//I suggest a habit of avoiding simple names when generating mixin code
                return mixin((){
                        string output="tuple(";
                        foreach(C;__s__){
                                output~=C;
                                output~=',';
                        }
                        output~=")";
                        return output;
                }());
        }
}
unittest{
        Vector!(3,int,"xyz") foo;
        foo.x=5;
        foo.y=3;
        foo.yx.writeln;
        Vector!(4,ubyte,"rgba") bar;
        bar.bgr.writeln;
}
```

I simplified your example, and manually expanded opDispatch so D newbies can grok it. Please explain the opDispatch IIFE and why no semicolon needed at the end.

```
import std;

// Comment out yx() xor opDispatch()

struct Vector(int N, T, string fields){
        int x;
        int y;
        int z;

        // manual expansion of opDispatch
        // auto yx() {
        //      string output = "tuple(";
        //      foreach (char scv; "yx") {
        //              output ~= scv;
        //              output ~= ",";
        //      }
        //      output ~= ")";
        //      writeln(output);                        // This is not in 
opDispatch()
        //      return tuple(3, 5);         // Hack to return same result
        // }

// I suggest a habit of avoiding simple names when generating mixin code
        auto opDispatch(string __s__)() {  // IIFE
                writeln("__s__: ", __s__);

                return mixin(() {
                        string output = "tuple(";
                        foreach (C; __s__){
                                output ~= C;
                                output ~= ',';
                        }
                        output ~= ")";
                        return output;
                } ());
        }
}

void main() {
        Vector!(3, int, "xyz") foo;
        foo.x = 5;              // Standard assignment to known member
        foo.y = 3;              // Standard assignment to known member
foo.yx.writeln; // yx not a member of Vector, so opDispatch is called
}}
```

Console output:
```
__s__: yx
Tuple!(int, int)(3, 5)
```

Reply via email to