Jump to page: 1 2
Thread overview
D equivalent of C++ bind ?
May 10, 2016
chmike
May 10, 2016
rikki cattermole
May 10, 2016
chmike
May 10, 2016
André
May 12, 2016
Dsby
May 10, 2016
Olivier Pisano
May 10, 2016
Gary Willoughby
May 12, 2016
Dsby
May 16, 2016
chmike
May 16, 2016
Dsby
May 17, 2016
chmike
May 10, 2016
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
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
Thanks. This does the job but it's not as concise.


May 10, 2016
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
Salut Christophe,

Did you have a look at https://dlang.org/phobos/std_functional.html#partial ?
May 10, 2016
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
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
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
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
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.

« First   ‹ Prev
1 2