digitalmars.D.learn - Code example for function/delegate as template argument ?
- chmike (8/8) May 03 2016 Hello,
- Basile B. (20/28) May 03 2016 Hello, you can use an alias this to pass a lmbda (or a delegate):
- chmike (5/11) May 04 2016 Is this equivalent to Foo!(a => a.writeln) or is it required to
- Basile B. (4/15) May 04 2016 Yes this is equivalent, the parens are not required. With a
- Basile B. (41/49) May 04 2016 As for the second question, finding the right method dynamically
- chmike (17/17) May 04 2016 I think you misunderstood the second question.
- H. S. Teoh via Digitalmars-d-learn (28/37) May 04 2016 The usual way is to use an alias argument:
Hello, I failed to find some code example for a template class/struct that accept a function/delegate as template argument. All examples I could find use simple value types like int or double. I piggy bag another question. Defining a function/delegate as function argument is shown in examples. What I could not find is how would I pass an object instance with a method to call ? In C++ we use std::bind. How do we do that in D ?
May 03 2016
On Wednesday, 4 May 2016 at 06:21:36 UTC, chmike wrote:Hello, I failed to find some code example for a template class/struct that accept a function/delegate as template argument. All examples I could find use simple value types like int or double. I piggy bag another question. Defining a function/delegate as function argument is shown in examples. What I could not find is how would I pass an object instance with a method to call ? In C++ we use std::bind. How do we do that in D ?Hello, you can use an alias this to pass a lmbda (or a delegate): ---- module runnable; import std.stdio; struct Foo(alias fun) { this(string text) { fun(text); } } void main(string[] args) { alias fun = (a) => a.writeln; auto foo = Foo!fun("hello"); } ---- I suppose that a constraint would be welcome be that's not the point here.
May 03 2016
On Wednesday, 4 May 2016 at 06:59:00 UTC, Basile B. wrote:. . . void main(string[] args) { alias fun = (a) => a.writeln; auto foo = Foo!fun("hello"); }Is this equivalent to Foo!(a => a.writeln) or is it required to split this in two instructions as you did ? I also thought the parenthesis around the lambda arguments are not required. Is that right ?
May 04 2016
On Wednesday, 4 May 2016 at 10:58:04 UTC, chmike wrote:On Wednesday, 4 May 2016 at 06:59:00 UTC, Basile B. wrote:Yes this is equivalent, the parens are not required. With a delegate literal they are: "auto foo = Foo!((a){a.writeln;})("hello");. . . void main(string[] args) { alias fun = (a) => a.writeln; auto foo = Foo!fun("hello"); }Is this equivalent to Foo!(a => a.writeln) or is it required to split this in two instructions as you did ? I also thought the parenthesis around the lambda arguments are not required. Is that right ?
May 04 2016
On Wednesday, 4 May 2016 at 06:21:36 UTC, chmike wrote:Hello, I failed to find some code example for a template class/struct that accept a function/delegate as template argument. All examples I could find use simple value types like int or double. I piggy bag another question. Defining a function/delegate as function argument is shown in examples. What I could not find is how would I pass an object instance with a method to call ? In C++ we use std::bind. How do we do that in D ?As for the second question, finding the right method dynamically (virtual method or interface) is easy so I suppose you want to find a member using D reflection. Here is a quick example: ---- struct Bar { void fun(string text) {text.writeln;} } struct Foo { void delegate(string) dg; this(T)(T t) { foreach(member; __traits(allMembers, T)) { foreach(i, overload; __traits(getOverloads, T, member)[]) { auto overloadDg = &__traits(getOverloads, t, member)[i]; static if (is(typeof(overloadDg) == typeof(dg))) { dg = &__traits(getOverloads, t, member)[i]; break; } } } if (dg) dg("found"); } } void main(string[] args) { Bar bar; Foo foo = Foo(bar); } ---- More checkings are possible. Here I just verify that a pointer to a member function is of same type as the delegate to assign.
May 04 2016
I think you misunderstood the second question. Here is another attempt with an example. // function accepting a function as argument void foo(function void fg(int)) { fg(5); } // A class with a none static method with the same signature as the argument function of foo class Bar { void fizz(int a) { writefln("Arg: %s", a); } } // An instance of class Bar auto bar = new Bar; // Calling foo by passing bar and the method fizz so that bar.fizz() is called when foo calls fg foo( ??? ); Does the argument type need to be a delegate ?
May 04 2016
On Wednesday, 4 May 2016 at 11:19:59 UTC, chmike wrote:I think you misunderstood the second question. Here is another attempt with an example. // function accepting a function as argument void foo(function void fg(int)) { fg(5); } // A class with a none static method with the same signature as the argument function of foo class Bar { void fizz(int a) { writefln("Arg: %s", a); } } // An instance of class Bar auto bar = new Bar; // Calling foo by passing bar and the method fizz so that bar.fizz() is called when foo calls fg foo( ??? ); Does the argument type need to be a delegate ?It's much more simple then. You need void foo(void delegate int() dg) {dg(5);} and yes it must be a delegate.
May 04 2016
On Wed, May 04, 2016 at 06:21:36AM +0000, chmike via Digitalmars-d-learn wrote:Hello, I failed to find some code example for a template class/struct that accept a function/delegate as template argument. All examples I could find use simple value types like int or double.The usual way is to use an alias argument: class MyClass(alias fun) if (is(typeof(fun(0)))) // assuming fun takes 1 int argument { void method() { fun(0); } }I piggy bag another question. Defining a function/delegate as function argument is shown in examples. What I could not find is how would I pass an object instance with a method to call ? In C++ we use std::bind. How do we do that in D ?You probably need a delegate, since a function (== function pointer) in D is a pointer to a (module-global) function with no context. If you need a context, e.g., an object instance, you need a delegate. Example: class C { void method(int x) { import std.stdio; writeln("bing!"); } } void fun(void delegate(int) dg) { dg(1); } void main() { auto c = new C; fun(&c.method); } T -- Long, long ago, the ancient Chinese invented a device that lets them see through walls. It was called the "window".
May 04 2016