Thread overview |
---|
January 11, 2021 Easy way to accept X and immutable X in parameters without overloading? | ||||
---|---|---|---|---|
| ||||
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)) { // ... } |
January 11, 2021 Re: Easy way to accept X and immutable X in parameters without overloading? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack | 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) { ... }
|
January 11, 2021 Re: Easy way to accept X and immutable X in parameters without overloading? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | On Monday, 11 January 2021 at 16:56:05 UTC, ag0aep6g wrote:
> 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) { ... }
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());
|
January 11, 2021 Re: Easy way to accept X and immutable X in parameters without overloading? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack | 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".)
|
January 11, 2021 Re: Easy way to accept X and immutable X in parameters without overloading? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ag0aep6g | On Monday, 11 January 2021 at 18:37:58 UTC, ag0aep6g wrote: > 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); I did exactly that and SList template initilization failed > 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); } |
January 11, 2021 Re: Easy way to accept X and immutable X in parameters without overloading? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack | 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.
|
January 11, 2021 Re: Easy way to accept X and immutable X in parameters without overloading? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack | 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.
|
Copyright © 1999-2021 by the D Language Foundation