Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
December 24, 2019 array of functions/delegates | ||||
---|---|---|---|---|
| ||||
I am trying to create an array of functions inside a struct. struct S { void f1() {} void f2() {} alias Func = void function(); immutable Func[2] = [&f1, &f2] } What I got: Error: non-constant expression '&f1' Tried also with delegates (since I am in a struct context but I got: no `this` to create delegate `f1`. So, is there any way to have an array of functions without adding them at runtime? |
December 24, 2019 Re: array of functions/delegates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rumbu | On Tuesday, 24 December 2019 at 07:37:02 UTC, Rumbu wrote: > I am trying to create an array of functions inside a struct. > > struct S { > void f1() {} > void f2() {} > > alias Func = void function(); > > immutable Func[2] = [&f1, &f2] > > } > > What I got: Error: non-constant expression '&f1' > > Tried also with delegates (since I am in a struct context but I got: no `this` to create delegate `f1`. > > So, is there any way to have an array of functions without adding them at runtime? If you don't need runtime, probably like this: ´´´ import std; void f1(S s) {assert(1);} void f2(S s) {assert(1);} alias field = AliasSeq!(f1, f2); struct S{} void main() { S s; field[0](s); } ´´´ Don't know why UCFS doesn't work in this case though. Maybe, this is also helpful: https://forum.dlang.org/post/mailman.2415.1354291433.5162.digitalmars-d-learn@puremagic.com |
December 24, 2019 Re: array of functions/delegates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rumbu | On Tuesday, 24 December 2019 at 07:37:02 UTC, Rumbu wrote:
> I am trying to create an array of functions inside a struct.
>
> struct S {
> void f1() {}
> void f2() {}
>
> alias Func = void function();
>
> immutable Func[2] = [&f1, &f2]
>
> }
>
> What I got: Error: non-constant expression '&f1'
>
> Tried also with delegates (since I am in a struct context but I got: no `this` to create delegate `f1`.
>
> So, is there any way to have an array of functions without adding them at runtime?
This isn't an array of functions you're creating here. A pointer to a member function is *always* a delegate, unless the function is static. Pointers to functions can be known at compile time, so this works:
struct S () {
static void f1() {}
static void f2() {}
alias Func = void function();
immutable Func[2] funcs = [&f1, &f2];
}
As does this:
struct S {}
void f1(S s) {}
void f2(S s) {}
alias Func = immutable(void function());
immutable Func[2] funcs = [cast(Func)&f1, cast(Func)&f2];
Though, it's not clear to me wy the one requires casting the pointer type and the other doesn't.
|
December 24, 2019 Re: array of functions/delegates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Parker | On Tuesday, 24 December 2019 at 10:40:16 UTC, Mike Parker wrote:
> struct S {}
> void f1(S s) {}
> void f2(S s) {}
>
> alias Func = immutable(void function());
>
> immutable Func[2] funcs = [cast(Func)&f1, cast(Func)&f2];
>
> Though, it's not clear to me wy the one requires casting the pointer type and the other doesn't.
Because typeof(&f1) == void function(S)
|
December 24, 2019 Re: array of functions/delegates | ||||
---|---|---|---|---|
| ||||
Posted in reply to MoonlightSentinel | On Tuesday, 24 December 2019 at 13:13:12 UTC, MoonlightSentinel wrote:
> On Tuesday, 24 December 2019 at 10:40:16 UTC, Mike Parker wrote:
>> struct S {}
>> void f1(S s) {}
>> void f2(S s) {}
>>
>> alias Func = immutable(void function());
>>
>> immutable Func[2] funcs = [cast(Func)&f1, cast(Func)&f2];
>>
>> Though, it's not clear to me wy the one requires casting the pointer type and the other doesn't.
>
> Because typeof(&f1) == void function(S)
Working example without casts using type deduction:
import std.stdio: writeln;
struct S {}
void f1(S s) { writeln("f1"); }
void f2(S s) { writeln("f2"); }
immutable funcs = [&f1, &f2];
void main() {
S s;
foreach(f; funcs) {
f(s);
}
}
|
December 24, 2019 Re: array of functions/delegates | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rumbu | On Tuesday, 24 December 2019 at 07:37:02 UTC, Rumbu wrote: > I am trying to create an array of functions inside a struct. > > struct S { > void f1() {} > void f2() {} > > alias Func = void function(); > > immutable Func[2] = [&f1, &f2] > > } > > What I got: Error: non-constant expression '&f1' > > Tried also with delegates (since I am in a struct context but I got: no `this` to create delegate `f1`. > > So, is there any way to have an array of functions without adding them at runtime? You can set funcs within the constructor but not as a default initializer because they have to be compile time constants (https://dlang.org/spec/struct.html#default_struct_init) struct S { void f1() {} void f2() {} alias Func = void delegate(); immutable Func[2] funcs; this(bool) { funcs = [&f1, &f2]; } } &f1 creates a delegate which contain a function pointer and the context pointer (struct, closure, ...). In this example the latter contains a pointer to a concrete instance of S which is a usually a runtime value. (https://dlang.org/spec/type.html#delegates) |
December 24, 2019 Re: array of functions/delegates | ||||
---|---|---|---|---|
| ||||
Posted in reply to MoonlightSentinel | On Tuesday, 24 December 2019 at 13:13:12 UTC, MoonlightSentinel wrote:
> On Tuesday, 24 December 2019 at 10:40:16 UTC, Mike Parker wrote:
>> struct S {}
>> void f1(S s) {}
>> void f2(S s) {}
>>
>> alias Func = immutable(void function());
>>
>> immutable Func[2] funcs = [cast(Func)&f1, cast(Func)&f2];
>>
>> Though, it's not clear to me wy the one requires casting the pointer type and the other doesn't.
>
> Because typeof(&f1) == void function(S)
Right. I didn't modify the alias declaration when I took the functions out of the struct. I saw the immutable in the error message and thought that was the problem.
alias Func = void function(S);
|
December 26, 2019 Re: array of functions/delegates | ||||
---|---|---|---|---|
| ||||
Posted in reply to MoonlightSentinel | On 12/24/19 8:52 AM, MoonlightSentinel wrote:
> On Tuesday, 24 December 2019 at 07:37:02 UTC, Rumbu wrote:
>> I am trying to create an array of functions inside a struct.
>>
>> struct S {
>> void f1() {}
>> void f2() {}
>>
>> alias Func = void function();
>>
>> immutable Func[2] = [&f1, &f2]
>>
>> }
>>
>> What I got: Error: non-constant expression '&f1'
>>
>> Tried also with delegates (since I am in a struct context but I got: no `this` to create delegate `f1`.
>>
>> So, is there any way to have an array of functions without adding them at runtime?
>
> You can set funcs within the constructor but not as a default initializer because they have to be compile time constants (https://dlang.org/spec/struct.html#default_struct_init)
>
> struct S
> {
> void f1() {}
> void f2() {}
>
> alias Func = void delegate();
>
> immutable Func[2] funcs;
>
> this(bool)
> {
> funcs = [&f1, &f2];
> }
> }
>
> &f1 creates a delegate which contain a function pointer and the context pointer (struct, closure, ...). In this example the latter contains a pointer to a concrete instance of S which is a usually a runtime value. (https://dlang.org/spec/type.html#delegates)
Just FYI, doing this is very suspicious. Storing a delegate to a struct means you have a context pointer to that struct. And structs can usually move around freely. Meaning that f1 and f2 are still going to refer to the original struct, even if it has been copied, and even if the struct has been deallocated (i.e. it was on a stack frame that no longer exists).
-Steve
|
Copyright © 1999-2021 by the D Language Foundation