Jump to page: 1 2
Thread overview
Can a member function return a delegate to itself?
May 23, 2007
Steve Teale
May 23, 2007
davidl
May 23, 2007
Frits van Bommel
May 23, 2007
BCS
May 23, 2007
Gregor Richards
May 23, 2007
BCS
May 24, 2007
teales
May 24, 2007
teales
May 24, 2007
BCS
May 23, 2007
Manfred Nowak
May 23, 2007
Something like:

class Foo
{
    int a;

    this() { a = 0; }

    void delegate(int) sum(int n)
              { a += n; return cast(void delegate(int)) &this.sum; }
}
May 23, 2007
Steve Teale wrote:
> Something like:
> 
> class Foo
> {
>     int a;
> 
>     this() { a = 0; }
> 
>     void delegate(int) sum(int n)               { a += n; return cast(void delegate(int)) &this.sum; }
> }

Yes, although you don't need the cast().

-- Chris Nicholson-Sauls
May 23, 2007
why would u need this ?
and imo D is not capable of doing so cause the return type of such a function
is not defined.





-- 
使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
May 23, 2007
Steve Teale wrote:
> Something like:
> 
> class Foo
> {
>     int a;
> 
>     this() { a = 0; }
> 
>     void delegate(int) sum(int n)               { a += n; return cast(void delegate(int)) &this.sum; }
> }

As said this can't be done because the return type of such a function would be it's own type, and so any description of the type would need to include itself as a (strict) substring. A type that cannot be described cannot be used.
However, there's a workaround:
---
class Foo
{
    int a;

    this() { a = 0; }

    // you can also put this into a struct member named "sum"
    // if you prefer
    Foo opCall(int n)
              { a += n; return this; }

    alias opCall sum;  // optional
}


// test code:
import std.stdio;

void main() {
	scope foo = new Foo;
	foo.sum(1)(2)(3);
	writefln(foo.a);        // writes '6'
}
---
(also popular with structs instead of classes. Or struct members of classes)
May 23, 2007
Steve Teale wrote:
> Something like:
> 
> class Foo
> {
>     int a;
> 
>     this() { a = 0; }
> 
>     void delegate(int) sum(int n)               { a += n; return cast(void delegate(int)) &this.sum; }
> }

as mentioned, the reason this isn't directly doable is that the type is undefinable. However this is strictly a limitation of the D Syntax and their is no problem with actually doing it if you can tell DMD how. I have does this using typing tricks before:


struct S
{
	S delegate(int,int) dg;
}

struct O
{
	int k;
	S go(int i, int j)
	{
		O* o = new O
		o.k = k+i+j;
		S ret;
		ret.dg = &o.go;
		return ret;
	}
}
May 23, 2007
BCS wrote:
> as mentioned, the reason this isn't directly doable is that the type is undefinable. However this is strictly a limitation of the D Syntax and their is no problem with actually doing it if you can tell DMD how. I have does this using typing tricks before:
> 
> 
> struct S
> {
>     S delegate(int,int) dg;
> }
> 
> struct O
> {
>     int k;
>     S go(int i, int j)
>     {
>         O* o = new O
>         o.k = k+i+j;
>         S ret;
>         ret.dg = &o.go;
>         return ret;
>     }
> }

I just want to say that this method is brilliant. It's easy to read and understand on a high and low level, and does everything you need it to do with no questions asked. Bravo.

 - Gregor Richards
May 23, 2007
Gregor Richards wrote:
> BCS wrote:
> 
>> as mentioned, the reason this isn't directly doable is that the type is undefinable. However this is strictly a limitation of the D Syntax and their is no problem with actually doing it if you can tell DMD how. I have does this using typing tricks before:
>>
>>
>> struct S
>> {
>>     S delegate(int,int) dg;
>> }
>>
>> struct O
>> {
>>     int k;
>>     S go(int i, int j)
>>     {
>>         O* o = new O
>>         o.k = k+i+j;
>>         S ret;
>>         ret.dg = &o.go;
>>         return ret;
>>     }
>> }
> 
> 
> I just want to say that this method is brilliant. It's easy to read and understand on a high and low level, and does everything you need it to do with no questions asked. Bravo.
> 
>  - Gregor Richards

A simple thank you would suffice. <g> Your welcome.
May 23, 2007
Steve Teale wrote

> Something like:
>     void delegate(int) sum(int n)
>               { a += n; return cast(void delegate(int)) &this.sum; }

might work with an auxiliary type definition `Th':

import std.stdio;
typedef T delegate() Th;
typedef Th delegate() T;
T g, h;
T f(){
  writefln( "returning own type");
  return g;
}
void main(){
  h= f();
}

-manfred
May 24, 2007
BCS Wrote:

> Steve Teale wrote:
> > Something like:
> > 
> > class Foo
> > {
> >     int a;
> > 
> >     this() { a = 0; }
> > 
> >     void delegate(int) sum(int n)
> >               { a += n; return cast(void delegate(int)) &this.sum; }
> > }
> 
> as mentioned, the reason this isn't directly doable is that the type is undefinable. However this is strictly a limitation of the D Syntax and their is no problem with actually doing it if you can tell DMD how. I have does this using typing tricks before:
> 
> 
> struct S
> {
> 	S delegate(int,int) dg;
> }
> 
> struct O
> {
> 	int k;
> 	S go(int i, int j)
> 	{
> 		O* o = new O
> 		o.k = k+i+j;
> 		S ret;
> 		ret.dg = &o.go;
> 		return ret;
> 	}
> }

I also think your solution is nifty. So the answer to my question is rather like what you suggested, but you have to add an opCall to S, as in:

import std.stdio;

struct S
{
        S delegate(int) dg;
        S opCall(int n) { dg(n); return *this; }
}

struct O
{
        int a;
        S sum(int i)
        {
                a += i;
                S ret;
                ret.dg = &#8721;
                return ret;
        }
}


void main(char[][] args)
{
   O o;
   o.sum(1)(2)(3);
   writefln("%d", o.a); // prints 6 as desired
}

It was just a curious question in the first place but you never know, somebody might find a use for it.
May 24, 2007
teales Wrote:

> BCS Wrote:
> 
> > Steve Teale wrote:
> > > Something like:
> > > 
> > > class Foo
> > > {
> > >     int a;
> > > 
> > >     this() { a = 0; }
> > > 
> > >     void delegate(int) sum(int n)
> > >               { a += n; return cast(void delegate(int)) &this.sum; }
> > > }
> > 
> > as mentioned, the reason this isn't directly doable is that the type is undefinable. However this is strictly a limitation of the D Syntax and their is no problem with actually doing it if you can tell DMD how. I have does this using typing tricks before:
> > 
> > 
> > struct S
> > {
> > 	S delegate(int,int) dg;
> > }
> > 
> > struct O
> > {
> > 	int k;
> > 	S go(int i, int j)
> > 	{
> > 		O* o = new O
> > 		o.k = k+i+j;
> > 		S ret;
> > 		ret.dg = &o.go;
> > 		return ret;
> > 	}
> > }
> 
> I also think your solution is nifty. So the answer to my question is rather like what you suggested, but you have to add an opCall to S, as in:
> 
> import std.stdio;
> 
> struct S
> {
>         S delegate(int) dg;
>         S opCall(int n) { dg(n); return *this; }
> }
> 
> struct O
> {
>         int a;
>         S sum(int i)
>         {
>                 a += i;
>                 S ret;
>                 ret.dg = &#8721;
>                 return ret;
>         }
> }
> 
> 
> void main(char[][] args)
> {
>    O o;
>    o.sum(1)(2)(3);
>    writefln("%d", o.a); // prints 6 as desired
> }
> 
> It was just a curious question in the first place but you never know, somebody might find a use for it.

Hmm, interesting, the system converted ret.dg = & s u m ; (ignore the spaces) to the math summation character
« First   ‹ Prev
1 2