digitalmars.D.learn - Easy way to accept X and immutable X in parameters without
- Jack (13/13) Jan 11 2021 let's say a I have this:
- ag0aep6g (3/16) Jan 11 2021 Accepting both mutable and immutable is what `const` is for:
- Jack (7/26) Jan 11 2021 thanks! now, how would I add const here?
- ag0aep6g (10/16) Jan 11 2021 You said you want the callbacks to accept both mutable and
- Jack (24/43) Jan 11 2021 What I want is store a instance of Callback, whose parameter
- ag0aep6g (8/26) Jan 11 2021 I'm assuming that you then want to call the callbacks on mutable
- Paul Backus (16/27) Jan 11 2021 You have a type mismatch. Changing the code to use explicit type
let's say a I have this: void f(X foo) { } but I'd like to make f() accept immutable X too so instead of cast away everywhere in the code where immutable(X) is passed to f() or make a overload for this, are there any way to accept both in same function? those function are callback-like functions, I have lots of them so already and would need to double, if I do add an overload just for the immutable. I did come up with something using templates, not sure if it's ugly: void f(T)(T x) if(is(T == C) || is(T == immutable(C)) { // ... }
Jan 11 2021
On Monday, 11 January 2021 at 16:40:01 UTC, Jack wrote:let's say a I have this: void f(X foo) { } but I'd like to make f() accept immutable X too so instead of cast away everywhere in the code where immutable(X) is passed to f() or make a overload for this, are there any way to accept both in same function? those function are callback-like functions, I have lots of them so already and would need to double, if I do add an overload just for the immutable. I did come up with something using templates, not sure if it's ugly: void f(T)(T x) if(is(T == C) || is(T == immutable(C)) { // ... }Accepting both mutable and immutable is what `const` is for: void f(const X foo) { ... }
Jan 11 2021
On Monday, 11 January 2021 at 16:56:05 UTC, ag0aep6g wrote:On Monday, 11 January 2021 at 16:40:01 UTC, Jack wrote:thanks! now, how would I add const here? import std.container : SList; auto l = SList!Callabck(); doesn't work: auto l = SList!(const(Callabck())); auto l = SList!(const Callabck());let's say a I have this: void f(X foo) { } but I'd like to make f() accept immutable X too so instead of cast away everywhere in the code where immutable(X) is passed to f() or make a overload for this, are there any way to accept both in same function? those function are callback-like functions, I have lots of them so already and would need to double, if I do add an overload just for the immutable. I did come up with something using templates, not sure if it's ugly: void f(T)(T x) if(is(T == C) || is(T == immutable(C)) { // ... }Accepting both mutable and immutable is what `const` is for: void f(const X foo) { ... }
Jan 11 2021
On Monday, 11 January 2021 at 18:12:17 UTC, Jack wrote:thanks! now, how would I add const here? import std.container : SList; auto l = SList!Callabck(); doesn't work: auto l = SList!(const(Callabck())); auto l = SList!(const Callabck());You said you want the callbacks to accept both mutable and immutable. So make the parameter `const` in the callback type: alias Callabck = void function(const X foo); If you wanted an `SList` of `const Callabck`s, you'd write that like so: auto l = SList!(const Callabck)(); But it seems like `SList` doesn't support const elements. And I don't think that's what you actually want anyways. (By the way, you've got a typo there in "Callabck".)
Jan 11 2021
On Monday, 11 January 2021 at 18:37:58 UTC, ag0aep6g wrote:On Monday, 11 January 2021 at 18:12:17 UTC, Jack wrote:I did exactly that and SList template initilization failedthanks! now, how would I add const here? import std.container : SList; auto l = SList!Callabck(); doesn't work: auto l = SList!(const(Callabck())); auto l = SList!(const Callabck());You said you want the callbacks to accept both mutable and immutable. So make the parameter `const` in the callback type: alias Callabck = void function(const X foo);If you wanted an `SList` of `const Callabck`s, you'd write that like so: auto l = SList!(const Callabck)(); But it seems like `SList` doesn't support const elements. And I don't think that's what you actually want anyways.What I want is store a instance of Callback, whose parameter accept both immutable and non-immutable (so I used const) in the SList but it failed to initialize(By the way, you've got a typo there in "Callabck".)oh i see but I did write this code just for this post anyway. Here's what I'm trying to make to work: import std.container : SList; class C { static immutable Foo = new C(); // .... } alias Callback = void function(const C, int); void main() { auto l = SList!Callback(); auto a = (C c, int d) { }; auto b = (C c, int d) { }; auto c = (const C c, int d) { }; l.insert(a); l.insert(b); l.insert(c); }
Jan 11 2021
On Monday, 11 January 2021 at 18:51:04 UTC, Jack wrote:Here's what I'm trying to make to work: import std.container : SList; class C { static immutable Foo = new C(); // .... } alias Callback = void function(const C, int); void main() { auto l = SList!Callback(); auto a = (C c, int d) { }; auto b = (C c, int d) { }; auto c = (const C c, int d) { }; l.insert(a); l.insert(b); l.insert(c); }I'm assuming that you then want to call the callbacks on mutable and immutable `C`s like `C.Foo`. You have to add `const` to the `a` and `b` functions, too: auto a = (const C c, int d) { }; auto b = (const C c, int d) { }; Without those `const`s, you have callbacks with mutable parameters being called on an immutable object. That cannot work.
Jan 11 2021
On Monday, 11 January 2021 at 18:51:04 UTC, Jack wrote:alias Callback = void function(const C, int); void main() { auto l = SList!Callback(); auto a = (C c, int d) { }; auto b = (C c, int d) { }; auto c = (const C c, int d) { }; l.insert(a); l.insert(b); l.insert(c); }You have a type mismatch. Changing the code to use explicit type annotations instead of `auto` makes the problem obvious: alias Callback = void function(const C, int); void main() { Callback a = (C c, int d) { }; // Error Callback b = (C c, int d) { }; // Error Callback c = (const C c, int d) { }; } The error message given is the same for both lines: Error: cannot implicitly convert expression `__lambda1` of type `void function(C c, int d) pure nothrow nogc safe` to `void function(const(C), int)` In other words, `a` and `b` are not valid Callbacks, because they take a mutable C argument instead of a const C argument.
Jan 11 2021