Thread overview |
---|
May 04, 2016 Code example for function/delegate as template 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 04, 2016 Re: Code example for function/delegate as template argument ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chmike | 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 04, 2016 Re: Code example for function/delegate as template argument ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chmike | 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 Re: Code example for function/delegate as template argument ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Basile B. | 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 Re: Code example for function/delegate as template argument ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Basile B. | 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 Re: Code example for function/delegate as template argument ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chmike | 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: >> . . . >> 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 ? Yes this is equivalent, the parens are not required. With a delegate literal they are: "auto foo = Foo!((a){a.writeln;})("hello"); |
May 04, 2016 Re: Code example for function/delegate as template argument ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chmike | 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 Re: Code example for function/delegate as template argument ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chmike | 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.
|
Copyright © 1999-2021 by the D Language Foundation