View mode: basic / threaded / horizontal-split · Log in · Help
February 21, 2012
delegate as memeber
struct stuff {
	private Exception delegate() exceptionBuilder = delegate Exception() {
		return new Exception("foobar");
	};
}

The following piece of code trigger a compiler error : delegate 
module.stuff.__dgliteral1 function literals cannot be class members

Why is that ? Is it a bug or a feature ?
February 21, 2012
Re: delegate as memeber
On Tuesday, 21 February 2012 at 15:22:15 UTC, deadalnix wrote:
> struct stuff {
> 	private Exception delegate() exceptionBuilder = delegate 
> Exception() {
> 		return new Exception("foobar");
> 	};
> }
>
> The following piece of code trigger a compiler error : delegate 
> module.stuff.__dgliteral1 function literals cannot be class 
> members
>
> Why is that ? Is it a bug or a feature ?

Delegates contain a context pointer. Your delegate literal has no 
context.

You can't initialize it with the address of a method, either. For 
struct methods, the context pointer is a pointer to the 
structure. You can't have a .init that contains a pointer to an 
instance. You probably want to use a function literal.
February 21, 2012
Re: delegate as memeber
Le 21/02/2012 16:32, Vladimir Panteleev a écrit :
> On Tuesday, 21 February 2012 at 15:22:15 UTC, deadalnix wrote:
>> struct stuff {
>> private Exception delegate() exceptionBuilder = delegate Exception() {
>> return new Exception("foobar");
>> };
>> }
>>
>> The following piece of code trigger a compiler error : delegate
>> module.stuff.__dgliteral1 function literals cannot be class members
>>
>> Why is that ? Is it a bug or a feature ?
>
> Delegates contain a context pointer. Your delegate literal has no context.
>
> You can't initialize it with the address of a method, either. For struct
> methods, the context pointer is a pointer to the structure. You can't
> have a .init that contains a pointer to an instance. You probably want
> to use a function literal.

It doesn't work with function either.

But I need delegate here. The default one doesn't require a context, but 
isn't it possible to pass null as a context, as none is needed ? This 
value can be changer later, and definitively require to be a delegate.
February 21, 2012
Re: delegate as memeber
A possible workaround is to initialize the delegate
in the object's constructor.
February 21, 2012
Re: delegate as memeber
Le 21/02/2012 16:48, Adam D. Ruppe a écrit :
> A possible workaround is to initialize the delegate
> in the object's constructor.

It is a struct. And struct don't have default constructor. It lead to 
very segfault prone code (I did try that).
February 21, 2012
Re: delegate as memeber
21.02.2012 17:24, deadalnix пишет:
> struct stuff {
> private Exception delegate() exceptionBuilder = delegate Exception() {
> return new Exception("foobar");
> };
> }
>
> The following piece of code trigger a compiler error : delegate 
> module.stuff.__dgliteral1 function literals cannot be class members
>
> Why is that ? Is it a bug or a feature ?
>

The compiler expects member initializers to be known at compile-time. 
Since delegate carries closure, and closure is a run-time phenomena, you 
cannot put it there. That's how I understand it, and I might be wrong. 
Anyway, something like this is possible as a workaround:

struct Foo {
private Exception dg() {
if( m_Dg ) return m_Dg();
return new Exception( "foobar" );
}

private Exception delegate() m_Dg = null;
}
February 21, 2012
Re: delegate as memeber
On 2012-02-21 16:55, deadalnix wrote:
> Le 21/02/2012 16:48, Adam D. Ruppe a écrit :
>> A possible workaround is to initialize the delegate
>> in the object's constructor.
>
> It is a struct. And struct don't have default constructor. It lead to
> very segfault prone code (I did try that).

You can implement a static opCall and use that instead of the constructor.

-- 
/Jacob Carlborg
February 21, 2012
Re: delegate as memeber
Le 21/02/2012 17:30, Mantis a écrit :
> 21.02.2012 17:24, deadalnix пишет:
>> struct stuff {
>> private Exception delegate() exceptionBuilder = delegate Exception() {
>> return new Exception("foobar");
>> };
>> }
>>
>> The following piece of code trigger a compiler error : delegate
>> module.stuff.__dgliteral1 function literals cannot be class members
>>
>> Why is that ? Is it a bug or a feature ?
>>
>
> The compiler expects member initializers to be known at compile-time.
> Since delegate carries closure, and closure is a run-time phenomena, you
> cannot put it there. That's how I understand it, and I might be wrong.
> Anyway, something like this is possible as a workaround:
>
> struct Foo {
> private Exception dg() {
> if( m_Dg ) return m_Dg();
> return new Exception( "foobar" );
> }
>
> private Exception delegate() m_Dg = null;
> }

I think this the best solution after all.

But still I think the original code should be an error only if it use 
data out of the delegate scope. If it doesn't, frame pointer doesn't 
matter and null can be passed.
February 21, 2012
Re: delegate as memeber
On Tue, Feb 21, 2012 at 08:01:18PM +0100, deadalnix wrote:
[...]
> But still I think the original code should be an error only if it
> use data out of the delegate scope. If it doesn't, frame pointer
> doesn't matter and null can be passed.

You could file an enhancement request, if one hasn't already been filed.


T

-- 
I'm still trying to find a pun for "punishment"...
February 22, 2012
Re: delegate as memeber
On Tuesday, 21 February 2012 at 15:41:58 UTC, deadalnix wrote:
> Le 21/02/2012 16:32, Vladimir Panteleev a écrit :
>> On Tuesday, 21 February 2012 at 15:22:15 UTC, deadalnix wrote:
>>> struct stuff {
>>> private Exception delegate() exceptionBuilder = delegate 
>>> Exception() {
>>> return new Exception("foobar");
>>> };
>>> }
>>>
>>> The following piece of code trigger a compiler error : 
>>> delegate
>>> module.stuff.__dgliteral1 function literals cannot be class 
>>> members
>>>
>>> Why is that ? Is it a bug or a feature ?
>>
>> Delegates contain a context pointer. Your delegate literal has 
>> no context.
>>
>> You can't initialize it with the address of a method, either. 
>> For struct
>> methods, the context pointer is a pointer to the structure. 
>> You can't
>> have a .init that contains a pointer to an instance. You 
>> probably want
>> to use a function literal.
>
> It doesn't work with function either.
>
> But I need delegate here. The default one doesn't require a 
> context, but isn't it possible to pass null as a context, as 
> none is needed ? This value can be changer later, and 
> definitively require to be a delegate.

struct stuff {
	private Exception function() exceptionBuilder =
		&defaultExceptionBuilder;
	
	private static Exception defaultExceptionBuilder() {
		return new Exception("foobar");
	};
}
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home