Re: array of functions/delegates

2019-12-26 Thread Steven Schveighoffer via Digitalmars-d-learn

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] = [, ]

}

What I got: Error: non-constant expression ''

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 = [, ];
     }
}

 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


Re: array of functions/delegates

2019-12-24 Thread Mike Parker via Digitalmars-d-learn
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), cast(Func)];

Though, it's not clear to me wy the one requires casting the 
pointer type and the other doesn't.


Because typeof() == 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);


Re: array of functions/delegates

2019-12-24 Thread MoonlightSentinel via Digitalmars-d-learn

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] = [, ]

}

What I got: Error: non-constant expression ''

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 = [, ];
}
}

 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)


Re: array of functions/delegates

2019-12-24 Thread MoonlightSentinel via Digitalmars-d-learn
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), cast(Func)];

Though, it's not clear to me wy the one requires casting the 
pointer type and the other doesn't.


Because typeof() == 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 = [, ];

void main() {
S s;
foreach(f; funcs) {
f(s);
}
}


Re: array of functions/delegates

2019-12-24 Thread MoonlightSentinel via Digitalmars-d-learn

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), cast(Func)];

Though, it's not clear to me wy the one requires casting the 
pointer type and the other doesn't.


Because typeof() == void function(S)


Re: array of functions/delegates

2019-12-24 Thread Mike Parker via Digitalmars-d-learn

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] = [, ]

}

What I got: Error: non-constant expression ''

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 = [, ];

}

As does this:

struct S {}
void f1(S s) {}
void f2(S s) {}

alias Func = immutable(void function());

immutable Func[2] funcs = [cast(Func), cast(Func)];

Though, it's not clear to me wy the one requires casting the 
pointer type and the other doesn't.







Re: array of functions/delegates

2019-12-24 Thread Alex via Digitalmars-d-learn

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] = [, ]

}

What I got: Error: non-constant expression ''

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-le...@puremagic.com


array of functions/delegates

2019-12-23 Thread Rumbu via Digitalmars-d-learn

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] = [, ]

}

What I got: Error: non-constant expression ''

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?