Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 10, 2016 D equivalent of C++ bind ? | ||||
---|---|---|---|---|
| ||||
Is there an equivalent in D of the C++11 std.bind template class [http://en.cppreference.com/w/cpp/utility/functional/bind] ? Here is a blog post showing different examples of its use https://oopscenities.net/2012/02/24/c11-stdfunction-and-stdbind/ A possible use case is for a callback function/delegate with the expected signature bool cb(int error). I would like to pass a function bool myCb(int error, ref int myArg) instead with the variable myArg being given as predefined argument. Here is an example. ---- int count = 0; bool myCb(int error, ref int myArg) { if (myArg >= 6) return false; writeln(++myArg); return true; } void async_task(void function(int error) cb) { . . . while cb(0) . . . } void main() { . . . async_task( ??? myCb ??? count ??? ); . . . } ---- In C++ we would write async_task(std::bind(myCb, std::placeholders::_1, count)); |
May 10, 2016 Re: D equivalent of C++ bind ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chmike | I know this really isn't what you want, but it may help you: void doFunc(int a, int b, string text) { import std.stdio : writeln; writeln(text, ": ", a, " <> ", b); } void receiver(void delegate(string text) del) { del("Hey"); } void main() { struct Binder { int a, b; void function(int, int, string) del; void call(string text) { del(a, b, text); } } Binder binder = Binder(1, 3, &doFunc); receiver(&binder.call); } |
May 10, 2016 Re: D equivalent of C++ bind ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to rikki cattermole | Thanks. This does the job but it's not as concise. |
May 10, 2016 Re: D equivalent of C++ bind ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chmike | On Tuesday, 10 May 2016 at 15:33:03 UTC, chmike wrote:
> Thanks. This does the job but it's not as concise.
I've never missed C++'s bind functionality because D has first class support for delegates.
If async_task is changed to the following:
void async_task(void delegate(int error) cb) { . . . while cb(0) . . . }
You could just adapt a call to it using a lambda function:
async_task( (error) => myCb(error, count) );
D makes sure the enclosing stack is copied to the heap and count is reachable. Maybe this helps...
Regards,
André
|
May 10, 2016 Re: D equivalent of C++ bind ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chmike | Salut Christophe, Did you have a look at https://dlang.org/phobos/std_functional.html#partial ? |
May 10, 2016 Re: D equivalent of C++ bind ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chmike | On Tuesday, 10 May 2016 at 09:39:53 UTC, chmike wrote: > Is there an equivalent in D of the C++11 std.bind template class See http://dlang.org/phobos/std_functional.html#partial |
May 12, 2016 Re: D equivalent of C++ bind ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chmike | On Tuesday, 10 May 2016 at 09:39:53 UTC, chmike wrote: > Is there an equivalent in D of the C++11 std.bind template class [http://en.cppreference.com/w/cpp/utility/functional/bind] ? > > Here is a blog post showing different examples of its use > https://oopscenities.net/2012/02/24/c11-stdfunction-and-stdbind/ > > > A possible use case is for a callback function/delegate with the expected signature bool cb(int error). I would like to pass a function bool myCb(int error, ref int myArg) instead with the variable myArg being given as predefined argument. > > Here is an example. > ---- > int count = 0; > > bool myCb(int error, ref int myArg) > { > if (myArg >= 6) > return false; > writeln(++myArg); > return true; > } > > void async_task(void function(int error) cb) { . . . while cb(0) . . . } > > void main() { > . . . > async_task( ??? myCb ??? count ??? ); > . . . > } > ---- > > In C++ we would write > > async_task(std::bind(myCb, std::placeholders::_1, count)); I write one, bind functon to a delegate. In here: https://github.com/putao-dev/collie/blob/master/source/collie/utils/functional.d this is the code: auto bind(T,Args...)(auto ref T fun,Args args) if (isCallable!(T)) { alias FUNTYPE = Parameters!(fun); static if(is(Args == void)) { static if(isDelegate!T) return fun; else return toDelegate(fun); } else static if(FUNTYPE.length > args.length) { alias DTYPE = FUNTYPE[args.length..$]; return delegate(DTYPE ars){ TypeTuple!(FUNTYPE) value; value[0..args.length] = args[]; value[args.length..$] = ars[]; return fun(value); }; } else { return delegate(){return fun(args);}; } } |
May 12, 2016 Re: D equivalent of C++ bind ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chmike | On Tuesday, 10 May 2016 at 15:33:03 UTC, chmike wrote:
> Thanks. This does the job but it's not as concise.
The std.functional.partial can not use in runtime, only on complier time.
and it can not bind args that more than one.
|
May 16, 2016 Re: D equivalent of C++ bind ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dsby | On Thursday, 12 May 2016 at 10:38:37 UTC, Dsby wrote:
> I write one, bind functon to a delegate.
>
> In here:
> https://github.com/putao-dev/collie/blob/master/source/collie/utils/functional.d
>
>
> this is the code:
>
> auto bind(T,Args...)(auto ref T fun,Args args) if (isCallable!(T))
> {
> alias FUNTYPE = Parameters!(fun);
> static if(is(Args == void))
> {
> static if(isDelegate!T)
> return fun;
> else
> return toDelegate(fun);
> }
> else static if(FUNTYPE.length > args.length)
> {
> alias DTYPE = FUNTYPE[args.length..$];
> return
> delegate(DTYPE ars){
> TypeTuple!(FUNTYPE) value;
> value[0..args.length] = args[];
> value[args.length..$] = ars[];
> return fun(value);
> };
> }
> else
> {
> return delegate(){return fun(args);};
> }
> }
Thank you. Would you agree to help me understand it ?
The only thing I don't understand is why the function template argument is defined as T and the argument as auto ref T fun. Why the auto ref and not alias T in the template argument list ?
This bind is better than Partial!() from std.functional since it accepts any number of parameters. But the given parameters are passed as first arguments of fun. The std::bind of C++ allows to bind any parameter in any order and eventually multiple times. It's really as if a new function was defined with a total liberty degree on its signature.
Anyway thank you very much.
|
May 16, 2016 Re: D equivalent of C++ bind ? | ||||
---|---|---|---|---|
| ||||
Posted in reply to chmike | On Monday, 16 May 2016 at 15:11:26 UTC, chmike wrote:
> On Thursday, 12 May 2016 at 10:38:37 UTC, Dsby wrote:
>
>> [...]
>
> Thank you. Would you agree to help me understand it ?
>
> The only thing I don't understand is why the function template argument is defined as T and the argument as auto ref T fun. Why the auto ref and not alias T in the template argument list ?
>
> This bind is better than Partial!() from std.functional since it accepts any number of parameters. But the given parameters are passed as first arguments of fun. The std::bind of C++ allows to bind any parameter in any order and eventually multiple times. It's really as if a new function was defined with a total liberty degree on its signature.
>
> Anyway thank you very much.
you can remove "auto ref". and I remove the "auto ref" in my use.
if used the "alias T", It can not handle all while when the T is a delegate.
in C++ std::bind, the arguments order you can sort by used. in D I do not find how to enablement.
|
Copyright © 1999-2021 by the D Language Foundation