Re: Any workaround for "closures are not yet supported in CTFE"?
On 08.12.21 03:05, Andrey Zherikov wrote: On Tuesday, 7 December 2021 at 18:50:04 UTC, Ali Çehreli wrote: I don't know whether the workaround works with your program but that delegate is the equivalent of the following struct (the struct should be faster because there is no dynamic context allocation). Note the type of 'dg' is changed accordingly: The problem with struct-based solution is that I will likely be stuck with only one implementation of delegate (i.e. opCall implementation). Or I'll have to implement dispatching inside opCall based on some "enum" by myself which seems weird to me. Do I miss anything? This seems to work, maybe it is closer to what you are looking for. ```d import std.stdio, std.traits, core.lifetime; struct CtDelegate(R,T...){ void* ctx; R function(T,void*) fp; R delegate(T) get(){ R delegate(T) dg; dg.ptr=ctx; dg.funcptr=cast(typeof(dg.funcptr))fp; return dg; } alias get this; this(void* ctx,R function(T,void*) fp){ this.ctx=ctx; this.fp=fp; } R opCall(T args){ return fp(args,ctx); } } auto makeCtDelegate(alias f,C)(C ctx){ static struct Ctx{ C ctx; } return CtDelegate!(ReturnType!(typeof(f)),ParameterTypeTuple!f[0..$-1])(new Ctx(forward!ctx), (ParameterTypeTuple!f[0..$-1] args,void* ctx){ auto r=cast(Ctx*)ctx; return f(r.ctx,forward!args); }); } struct A{ CtDelegate!void[] dg; } auto createDelegate(string s){ return makeCtDelegate!((string s){ s.writeln; })(s); } A create(){ A a; a.dg ~= createDelegate("hello"); a.dg ~= createDelegate("buy"); return a; } void main(){ static a = create(); foreach(dg; a.dg) dg(); } ```
Re: Any workaround for "closures are not yet supported in CTFE"?
On Wednesday, 8 December 2021 at 07:55:55 UTC, Timon Gehr wrote: On 08.12.21 03:05, Andrey Zherikov wrote: On Tuesday, 7 December 2021 at 18:50:04 UTC, Ali Çehreli wrote: I don't know whether the workaround works with your program but that delegate is the equivalent of the following struct (the struct should be faster because there is no dynamic context allocation). Note the type of 'dg' is changed accordingly: The problem with struct-based solution is that I will likely be stuck with only one implementation of delegate (i.e. opCall implementation). Or I'll have to implement dispatching inside opCall based on some "enum" by myself which seems weird to me. Do I miss anything? This seems to work, maybe it is closer to what you are looking for. ```d import std.stdio, std.traits, core.lifetime; struct CtDelegate(R,T...){ void* ctx; R function(T,void*) fp; R delegate(T) get(){ R delegate(T) dg; dg.ptr=ctx; dg.funcptr=cast(typeof(dg.funcptr))fp; return dg; } alias get this; this(void* ctx,R function(T,void*) fp){ this.ctx=ctx; this.fp=fp; } R opCall(T args){ return fp(args,ctx); } } auto makeCtDelegate(alias f,C)(C ctx){ static struct Ctx{ C ctx; } return CtDelegate!(ReturnType!(typeof(f)),ParameterTypeTuple!f[0..$-1])(new Ctx(forward!ctx), (ParameterTypeTuple!f[0..$-1] args,void* ctx){ auto r=cast(Ctx*)ctx; return f(r.ctx,forward!args); }); } struct A{ CtDelegate!void[] dg; } auto createDelegate(string s){ return makeCtDelegate!((string s){ s.writeln; })(s); } A create(){ A a; a.dg ~= createDelegate("hello"); a.dg ~= createDelegate("buy"); return a; } void main(){ static a = create(); foreach(dg; a.dg) dg(); } ``` Incidentally, yesterday I played with a very similar solution. Here's my version: https://run.dlang.io/gist/PetarKirov/f347e59552dd87c4c02d0ce87d0e9cdc?compiler=dmd ```d interface ICallable { void opCall() const; } auto makeDelegate(alias fun, Args...)(auto ref Args args) { return new class(args) ICallable { Args m_args; this(Args p_args) { m_args = p_args; } void opCall() const { fun(m_args); } }; } alias Action = void delegate(); Action createDelegate(string s) { import std.stdio; return !((string str) => writeln(str))(s).opCall; } struct A { Action[] dg; } A create() { A a; a.dg ~= createDelegate("hello"); a.dg ~= createDelegate("buy"); return a; } void main() { enum a = create(); foreach(dg; a.dg) dg(); } ```
Re: Struct fields and properties as alias members
On Wednesday, 8 December 2021 at 17:44:47 UTC, Adam D Ruppe wrote: On Wednesday, 8 December 2021 at 17:19:32 UTC, Ben Jones wrote: Gotcha, thanks. I tried using `S.field` before and that didn't work, `__traits(child)` was the key. Since I reuse the field a few times I tried to alias the result: `alias theProp = __traits(child, s, field);` But everywhere I use `theProp` I get the same error as before (need this...). Is there a way to avoid using the full `__traits(child)` expression everywhere?
Re: Struct fields and properties as alias members
On Wednesday, 8 December 2021 at 18:07:32 UTC, Ben Jones wrote: Since I reuse the field a few times I tried to alias the result: `alias theProp = __traits(child, s, field);` yeah won't work since the alias again drops the `this`, this is the same thing as the template param. You could make a couple helper functions though. Like void set(typeof(field) v) { __traits(child, s, field) = v; } typeof(field) get() { return __traits(child, s, field); } just declare them nested inside the function and then you can use get and set as-needed. You could make a mixin or whatever if there's a bunch of functions doing this. Of course another idea is to make a helper struct that just wraps the field with opAssign and alias this or something but then it needs to keep a pointer back to s inside that object.
Re: Struct fields and properties as alias members
On Wednesday, 8 December 2021 at 18:23:25 UTC, Adam D Ruppe wrote: On Wednesday, 8 December 2021 at 18:07:32 UTC, Ben Jones wrote: I went with the mixin approach, which seems to work fine except that I couldn't declare the mixin inside a function, so the definition is pretty far away from use, but that's not a showstopper. Thanks for your excellent explanations + suggestions
Re: How to loop through characters of a string in D language?
On Wednesday, 8 December 2021 at 11:23:45 UTC, BoQsc wrote: The string example to loop/iterate: foreach(ch; a) { } does the individual chars of the string you can also foreach(dchar ch; a) { } to decode the utf 8
Re: How to loop through characters of a string in D language?
On Wednesday, 8 December 2021 at 11:35:39 UTC, Biotronic wrote: On Wednesday, 8 December 2021 at 11:23:45 UTC, BoQsc wrote: Let's say I want to skip characters and build a new string. The string example to loop/iterate: ``` import std.stdio; void main() { string a="abc;def;ab"; } ``` The character I want to skip: `;` Expected result: ``` abcdefab ``` [..] string b = a.filter!(c => c != ';').to!string; writeln(b); } I somehow have universal cross language hate for this kind of algorithm. I'm not getting used to the syntax and that leads to poor readability. But that might be just me. Anyways, Here is what I've come up with. ``` import std.stdio; void main() { string a = "abc;def;ab"; string b; for(int i=0; i
How to loop through characters of a string in D language?
Let's say I want to skip characters and build a new string. The string example to loop/iterate: ``` import std.stdio; void main() { string a="abc;def;ab"; } ``` The character I want to skip: `;` Expected result: ``` abcdefab ```
Re: Any workaround for "closures are not yet supported in CTFE"?
On Wednesday, 8 December 2021 at 08:07:59 UTC, Petar Kirov [ZombineDev] wrote: ```d interface ICallable { void opCall() const; } alias Action = void delegate(); struct A { Action[] dg; } ``` At this point why not just call a spade a spade and store an array of ICallables directly? :) I mean, why store fat pointers to fat pointers?
Re: How to loop through characters of a string in D language?
On Wednesday, 8 December 2021 at 12:49:39 UTC, Adam D Ruppe wrote: On Wednesday, 8 December 2021 at 11:23:45 UTC, BoQsc wrote: The string example to loop/iterate: foreach(ch; a) { } does the individual chars of the string you can also foreach(dchar ch; a) { } to decode the utf 8 Thanks Adam. This is how it would look implemented. ``` import std.stdio; void main() { string a = "abc;def;ab"; string b; foreach(ch; a) { if (ch != ';'){ b ~= ch; } writeln(ch); } writeln(b); } ```
Re: How to loop through characters of a string in D language?
On Wednesday, 8 December 2021 at 11:23:45 UTC, BoQsc wrote: Let's say I want to skip characters and build a new string. The string example to loop/iterate: ``` import std.stdio; void main() { string a="abc;def;ab"; } ``` The character I want to skip: `;` Expected result: ``` abcdefab ``` string b = a.replace(";", "");
Re: How to loop through characters of a string in D language?
On Wednesday, 8 December 2021 at 14:16:16 UTC, bauss wrote: On Wednesday, 8 December 2021 at 11:23:45 UTC, BoQsc wrote: Let's say I want to skip characters and build a new string. The string example to loop/iterate: ``` import std.stdio; void main() { string a="abc;def;ab"; } ``` The character I want to skip: `;` Expected result: ``` abcdefab ``` string b = a.replace(";", ""); Thanks, that's what I used to do few years ago. It's a great solution I forget about and it works. ``` import std.stdio; import std.array; void main() { string a="abc;def;ab"; string b = a.replace(";", ""); writeln(b); } ```
Re: How to loop through characters of a string in D language?
On Wednesday, 8 December 2021 at 11:23:45 UTC, BoQsc wrote: Let's say I want to skip characters and build a new string. The string example to loop/iterate: ``` import std.stdio; void main() { string a="abc;def;ab"; } ``` The character I want to skip: `;` Expected result: ``` abcdefab ``` import std.stdio : writeln; import std.algorithm.iteration : filter; import std.conv : to; void main() { string a = "abc;def;ab"; string b = a.filter!(c => c != ';').to!string; writeln(b); }
Re: Any workaround for "closures are not yet supported in CTFE"?
On 12/8/21 9:07 AM, Petar Kirov [ZombineDev] wrote: On Wednesday, 8 December 2021 at 07:55:55 UTC, Timon Gehr wrote: On 08.12.21 03:05, Andrey Zherikov wrote: On Tuesday, 7 December 2021 at 18:50:04 UTC, Ali Çehreli wrote: I don't know whether the workaround works with your program but that delegate is the equivalent of the following struct (the struct should be faster because there is no dynamic context allocation). Note the type of 'dg' is changed accordingly: The problem with struct-based solution is that I will likely be stuck with only one implementation of delegate (i.e. opCall implementation). Or I'll have to implement dispatching inside opCall based on some "enum" by myself which seems weird to me. Do I miss anything? This seems to work, maybe it is closer to what you are looking for. ... Incidentally, yesterday I played with a very similar solution. Here's my version: https://run.dlang.io/gist/PetarKirov/f347e59552dd87c4c02d0ce87d0e9cdc?compiler=dmd ```d interface ICallable { void opCall() const; } auto makeDelegate(alias fun, Args...)(auto ref Args args) { return new class(args) ICallable { Args m_args; this(Args p_args) { m_args = p_args; } void opCall() const { fun(m_args); } }; } alias Action = void delegate(); Action createDelegate(string s) { import std.stdio; return !((string str) => writeln(str))(s).opCall; } struct A { Action[] dg; } A create() { A a; a.dg ~= createDelegate("hello"); a.dg ~= createDelegate("buy"); return a; } void main() { enum a = create(); foreach(dg; a.dg) dg(); } ``` Nice, so the error message is lying. This is a bit more complete: ```d import std.stdio, std.traits, core.lifetime; auto partiallyApply(alias fun,C...)(C context){ return class(move(context)){ C context; this(C context) { foreach(i,ref c;this.context) c=move(context[i]); } auto opCall(ParameterTypeTuple!fun[context.length..$] args) { return fun(context,forward!args); } }.opCall; } alias Action = void delegate(); Action createDelegate(string s){ import std.stdio; return partiallyApply!((string str) => writeln(str))(s); } struct A{ Action[] dg; } A create(){ A a; a.dg ~= createDelegate("hello"); a.dg ~= createDelegate("buy"); return a; } void main(){ enum a = create(); foreach(dg; a.dg) dg(); } ```
Re: Struct fields and properties as alias members
On Wed, Dec 08, 2021 at 05:19:32PM +, Ben Jones via Digitalmars-d-learn wrote: > I'm trying to use a property member of a struct as a template alias > parameter and I don't really understand how to fix the error message > I'm seeing (I also tried the simpler case of a plain struct member, > and that didn't work either). Is what I'm trying to do possible? It > seems like maybe I'd have to pass s as a runtime parameter to get it > to work? It might help if you elaborate a bit more on what exactly you're trying to achieve here. Why can't you just pass the value of the field to the function as a runtime parameter, for example, which would be the usual way of doing it? Is there something specific you're trying to achieve here that requires using a template parameter? T -- Being forced to write comments actually improves code, because it is easier to fix a crock than to explain it. -- G. Steele
Re: Struct fields and properties as alias members
On Wednesday, 8 December 2021 at 17:29:19 UTC, H. S. Teoh wrote: On Wed, Dec 08, 2021 at 05:19:32PM +, Ben Jones via Digitalmars-d-learn wrote: I'm trying to use a property member of a struct as a template alias parameter and I don't really understand how to fix the error message I'm seeing (I also tried the simpler case of a plain struct member, and that didn't work either). Is what I'm trying to do possible? It seems like maybe I'd have to pass s as a runtime parameter to get it to work? It might help if you elaborate a bit more on what exactly you're trying to achieve here. Why can't you just pass the value of the field to the function as a runtime parameter, for example, which would be the usual way of doing it? Is there something specific you're trying to achieve here that requires using a template parameter? T It's a CPU simulator and the function needs to operate on half of a register (the CPU has 16 bit AF register, but I want to operate on A). I've implemented the "A" part of the register as a pair of property functions: ``` @property ubyte a() const { return getHigh!af; } @property ubyte a(ubyte val) { return setHigh!af(val); } ``` There are CPU instructions for each of the combined (AF, BC, DE, etc) and half(A, B, C, D, E, etc) registers, so I think either the half registers or the full registers would have to be implemented as property functions (from my reading of the spec, using unions seemed like technically it would be UB?) Basically I want to write one template for the operation (increment, load, etc), and then instantiate it for each register (inc a, inc b, inc c, load a, load b, etc)
Struct fields and properties as alias members
I'm trying to use a property member of a struct as a template alias parameter and I don't really understand how to fix the error message I'm seeing (I also tried the simpler case of a plain struct member, and that didn't work either). Is what I'm trying to do possible? It seems like maybe I'd have to pass s as a runtime parameter to get it to work? ``` import std.stdio; struct S{ int a = 1; int b = 2; @property int c(){ return a; } @property int c(int newc) { a = newc; return a;} } void func(alias field)(){ writeln(field); field = 5; } void main(){ S s; func!(s.a)(); func!(s.b)(); func!(s.c)(); } ``` Runnable link here: https://run.dlang.io/is/WHM1Er Errors: ``` onlineapp.d(17): Error: need `this` for `func` of type `@safe void()` onlineapp.d(18): Error: need `this` for `func` of type `@safe void()` onlineapp.d(12): Error: need `this` for `c` of type `@property int()` onlineapp.d(13): Error: need `this` for `c` of type `@property int(int newc)` onlineapp.d(20): Error: template instance `onlineapp.func!(c)` error instantiating ```
Re: Struct fields and properties as alias members
On Wednesday, 8 December 2021 at 17:19:32 UTC, Ben Jones wrote: I considered just having a `ref int` parameter, but I didn't think that would work if I was actually calling a property function, rather than just modifying a struct member. I also tried to use a template mixin, but couldn't get that to work either.
Re: Struct fields and properties as alias members
On Wed, Dec 08, 2021 at 05:21:49PM +, Ben Jones via Digitalmars-d-learn wrote: [...] > I considered just having a `ref int` parameter, but I didn't think > that would work if I was actually calling a property function, rather > than just modifying a struct member. [...] Why not pass the entire struct by ref? T -- Who told you to swim in Crocodile Lake without life insurance??
Re: Struct fields and properties as alias members
On Wednesday, 8 December 2021 at 17:19:32 UTC, Ben Jones wrote: It seems like maybe I'd have to pass s as a runtime parameter to get it to work? yes, you do. the alias param passes the abstract idea of the variable instead of the variable: void main(){ S s; func!(s.a)(); See, you said `s` here, but the compiler ACTUALLY passes `S.a` - the type reference instead of the instance reference. That's why it complains about missing `this` - the compiler dropped it. The `this` is a runtime reference, and the alias works on compile time references. You can pass a runtime reference in addition to the alias and put them back together with __traits(child), but be warned, the compiler also can get pretty stupid when pass so you need to make `func` static since when it sees the alias it assumes it must be a member. Weird but easy fix: ``` import std.stdio; struct S{ int a = 1; int b = 2; @property int c(){ return a; } @property int c(int newc) { a = newc; return a;} } // made static, added a ref S to act as `this` static void func(alias field)(ref S s){ // now the traits child re-attaches `s` as the this // reference to the alias writeln(__traits(child, s, field)); __traits(child, s, field) = 5; } void main(){ S s; func!(s.a)(s); // passing both ct alias and runtime this func!(s.b)(s); func!(s.c)(s); } ```
Re: How to loop through characters of a string in D language?
On Wednesday, 8 December 2021 at 22:35:35 UTC, Stanislav Blinov wrote: You're passing a literal. Try passing a runtime value (e.g. a command line argument). Also, -O2 -release :) Uless, of course, your goal is to look at debug code. but this will change nothing. the compilation cost of using .replace, will always be apparent (compared to the presented alternative), both in less time taken to compile, and smaller size of executable.
Re: Any workaround for "closures are not yet supported in CTFE"?
On Wednesday, 8 December 2021 at 17:05:49 UTC, Timon Gehr wrote: On 12/8/21 9:07 AM, Petar Kirov [ZombineDev] wrote: [...] Nice, so the error message is lying. Closure support deserves way more love in the compiler. I'm quite surprised that that hack worked, given that various very similar rearrangements that I tried before didn't. This is a bit more complete: ```d import std.stdio, std.traits, core.lifetime; auto partiallyApply(alias fun,C...)(C context){ return class(move(context)){ C context; this(C context) { foreach(i,ref c;this.context) c=move(context[i]); } auto opCall(ParameterTypeTuple!fun[context.length..$] args) { return fun(context,forward!args); } }.opCall; } // [snip] ``` Thanks, I was struggling to find a good name for this building block. `partiallyApply` is a natural fit. Also thanks for the move / forwarding icing.
T... args!
Hi all, Is this not a contradiction? : and 3.1415 aren't string: ```d void foo(string...)(string args) { foreach(ref str; args) { str.writeln('\t', typeof(str).stringof); } } foo("Pi", "number", ':', 3.1415); /* Pi string number string : char 3,1415 double //*/ ```
Re: T... args!
On Wednesday, 8 December 2021 at 23:47:07 UTC, Adam Ruppe wrote: On Wednesday, 8 December 2021 at 23:43:48 UTC, Salih Dincer wrote: I think you meant to say void foo(string[] args...) {} Not exactly... ```d alias str = immutable(char)[]; void foo(str...)(str args) { foreach(ref a; args) { a.writeln('\t', typeof(a).stringof); } str s; // "Amazing! ---v"; s.writeln(": ", typeof(s).stringof); } ```
Re: Any workaround for "closures are not yet supported in CTFE"?
On Wednesday, 8 December 2021 at 12:17:42 UTC, Stanislav Blinov wrote: On Wednesday, 8 December 2021 at 08:07:59 UTC, Petar Kirov [ZombineDev] wrote: ```d interface ICallable { void opCall() const; } alias Action = void delegate(); struct A { Action[] dg; } ``` At this point why not just call a spade a spade and store an array of ICallables directly? :) I mean, why store fat pointers to fat pointers? Initially that's exactly what I tried, and it worked if the result was stored as `static const` / `static immutable`, but it didn't when using the `enum`: ``` onlineapp.d(39): Error: variable `onlineapp.main.a` : Unable to initialize enum with class or pointer to struct. Use static const variable instead. ``` ```d interface ICallable { void opCall() const; } auto makeDelegate(alias fun, Args...)(auto ref Args args) { return new class(args) ICallable { Args m_args; this(Args p_args) { m_args = p_args; } void opCall() const { fun(m_args); } }; } alias Action = void delegate(); ICallable createDelegate(string s) { import std.stdio; return makeDelegate!((string str) => writeln(str))(s); } struct A { ICallable[] dg; } A create() { A a; a.dg ~= createDelegate("hello"); a.dg ~= createDelegate("buy"); return a; } void main() { enum a = create(); foreach(dg; a.dg) dg(); } ``` I didn't have time to fully investigate the issue and report this compiler limitation.
Re: How to loop through characters of a string in D language?
On Wednesday, 8 December 2021 at 14:27:22 UTC, BoQsc wrote: On Wednesday, 8 December 2021 at 14:16:16 UTC, bauss wrote: On Wednesday, 8 December 2021 at 11:23:45 UTC, BoQsc wrote: Let's say I want to skip characters and build a new string. The string example to loop/iterate: ``` import std.stdio; void main() { string a="abc;def;ab"; } ``` The character I want to skip: `;` Expected result: ``` abcdefab ``` string b = a.replace(";", ""); Thanks, that's what I used to do few years ago. It's a great solution I forget about and it works. ``` import std.stdio; import std.array; void main() { string a="abc;def;ab"; string b = a.replace(";", ""); writeln(b); } ``` It's also worth noting the differences in compiler output, as well as the time taken to compile, these two approaches: (1) string str = "abc;def;ab".filter!(c => c != ';').to!string; (2) string str = "abc;def;ab".replace(";", ""); see: https://d.godbolt.org/z/3dWYsEGsr
Re: How to loop through characters of a string in D language?
On Wednesday, 8 December 2021 at 22:18:23 UTC, forkit wrote: It's also worth noting the differences in compiler output, as well as the time taken to compile, these two approaches: (1) string str = "abc;def;ab".filter!(c => c != ';').to!string; (2) string str = "abc;def;ab".replace(";", ""); see: https://d.godbolt.org/z/3dWYsEGsr You're passing a literal. Try passing a runtime value (e.g. a command line argument). Also, -O2 -release :) Uless, of course, your goal is to look at debug code.
Re: How to loop through characters of a string in D language?
On Wednesday, 8 December 2021 at 22:55:02 UTC, forkit wrote: On Wednesday, 8 December 2021 at 22:35:35 UTC, Stanislav Blinov wrote: You're passing a literal. Try passing a runtime value (e.g. a command line argument). Also, -O2 -release :) Uless, of course, your goal is to look at debug code. but this will change nothing. the compilation cost of using .replace, will always be apparent (compared to the presented alternative), both in less time taken to compile, and smaller size of executable. well... maybe not that apparent afterall ;-) .. the mysteries of compiler optimisation
Re: T... args!
On Wednesday, 8 December 2021 at 23:43:48 UTC, Salih Dincer wrote: Is this not a contradiction? : and 3.1415 aren't string: ```d void foo(string...)(string args) { `string...` there is a user-defined identifier representing a mix of types. string isn't special, yo can declare your own variables with that name. And that's what you did here. I think you meant to say void foo(string[] args...) {} which is avariadtic number of only strings
Re: How to loop through characters of a string in D language?
On Wednesday, 8 December 2021 at 11:23:45 UTC, BoQsc wrote: Let's say I want to skip characters and build a new string. The string example to loop/iterate: ``` import std.stdio; void main() { string a="abc;def;ab"; } ``` The character I want to skip: `;` Expected result: ``` abcdefab ``` I always use split() and joiner pair. You can customize it as you want: ```d import std.stdio : writeln; import std.algorithm : joiner; import std.array : split; bool isWhite(dchar c) @safe pure nothrow @nogc { return c == ' ' || c == ';' || (c >= 0x09&& c <= 0x0D); } void main() { string str = "a\nb c\t;d e f;a b "; str.split!isWhite.joiner.writeln(); //abcdefab } ```
Re: Any workaround for "closures are not yet supported in CTFE"?
On Wednesday, 8 December 2021 at 17:05:49 UTC, Timon Gehr wrote: ```d import std.stdio, std.traits, core.lifetime; auto partiallyApply(alias fun,C...)(C context){ return class(move(context)){ C context; this(C context) { foreach(i,ref c;this.context) c=move(context[i]); } auto opCall(ParameterTypeTuple!fun[context.length..$] args) { return fun(context,forward!args); } }.opCall; } alias Action = void delegate(); Action createDelegate(string s){ import std.stdio; return partiallyApply!((string str) => writeln(str))(s); } struct A{ Action[] dg; } A create(){ A a; a.dg ~= createDelegate("hello"); a.dg ~= createDelegate("buy"); return a; } void main(){ enum a = create(); foreach(dg; a.dg) dg(); } ``` This is great, thanks you!
Re: C++ bindings: const(T) dropped in return types of templates ?
On Monday, 6 December 2021 at 20:31:47 UTC, Jan wrote: So am I missing something, or did the compiler somehow forget about the const-ness? Sounds like a bug to me, eg this one: https://issues.dlang.org/show_bug.cgi?id=20685