View mode: basic / threaded / horizontal-split · Log in · Help
February 14, 2008
Re: *final* class member (D2)
On Thu, 14 Feb 2008 08:53:23 +0900, Neil Vice wrote:

> 
> "Denton Cockburn" <diboss@hotmail.com> wrote in message 
> news:pan.2008.02.13.22.55.38.263151@hotmail.com...
>> On Wed, 13 Feb 2008 14:33:33 -0500, Steven Schveighoffer wrote:
>>
>>> "Denton Cockburn" wrote
>>>> How do I do this?  I'm trying to create a class member here that needs 
>>>> to
>>>> be initialized in the constructor, but cannot be changed later.
>>>>
>>>> class A
>>>> {
>>>>   (const doesn't work) real delegate() dg; // this is that
>>>>   function;
>>>>
>>>>   this(real delegate() dg) { this.dg = dg; }
>>>> }
>>>>
>>>> class B
>>>> {
>>>>   real foo() { return 3.5; }
>>>> }
>>>>
>>>> class C
>>>> {
>>>>   real foo() { return 4.5; }
>>>> }
>>>>
>>>> void main()
>>>> {
>>>>   auto b = new B;
>>>>   auto a = new A(&b.foo);
>>>>   auto c = new C;
>>>>   a.fitness = &c.foo; // I want this to be an error
>>>> }
>>>
>>> um... did you try encapsulation?
>>>
>>> class A
>>> {
>>>    private real delegate() _dg;
>>>
>>>    public real dg()
>>>    {
>>>       return _dg();
>>>    }
>>>
>>>    this(real delegate() dg) { this._dg = dg; }
>>> }
>>>
>>> -Steve
>>
>> This was the workaround I used as well.
>> I don't like it because of the extra level of indirection (I end up
>> calling 2 functions instead of 1).  I don't consider this very efficient
>> or convenient.
> 
> I would have expected the dg() method (or property I guess) in the above to 
> be inlined, possibly requiring a final specifier? In that case I don't see 
> any reduction in performance.
> 
> As a matter of interest the following code is fairly equivalent but results 
> in some bizarre property/delegate interaction:
> 
> class A
> {
>     private real delegate() _dg;
> 
>     this(real delegate() dg) { this._dg = dg; }
> 
>     public real delegate() dg()
>     {
>         return _dg;
>     }
> }
> 
> // Sample usage
> public void example(real delegate() dg)
> {
>     A test = new A(dg);
>     // test.dg        - Evaluates to the delegate dg
>     // test.dg()     - Also evaluates to the delegate dg
>     test.dg()()      // Required to actually execute the delegate
> }
> 
> Neil

isn't that because you have the function (test.dg) return a "real
delegate()" so: test.dg() returns a delegate, and test.dg()() calls that
delegate.
February 14, 2008
Re: *final* class member (D2)
"Denton Cockburn" <diboss@hotmail.com> wrote in message 
news:pan.2008.02.14.00.52.40.389590@hotmail.com...
> On Thu, 14 Feb 2008 08:53:23 +0900, Neil Vice wrote:
>
>>
>> "Denton Cockburn" <diboss@hotmail.com> wrote in message
>> news:pan.2008.02.13.22.55.38.263151@hotmail.com...
>>> On Wed, 13 Feb 2008 14:33:33 -0500, Steven Schveighoffer wrote:
>>>
>>>> "Denton Cockburn" wrote
>>>>> How do I do this?  I'm trying to create a class member here that needs
>>>>> to
>>>>> be initialized in the constructor, but cannot be changed later.
>>>>>
>>>>> class A
>>>>> {
>>>>>   (const doesn't work) real delegate() dg; // this is that
>>>>>   function;
>>>>>
>>>>>   this(real delegate() dg) { this.dg = dg; }
>>>>> }
>>>>>
>>>>> class B
>>>>> {
>>>>>   real foo() { return 3.5; }
>>>>> }
>>>>>
>>>>> class C
>>>>> {
>>>>>   real foo() { return 4.5; }
>>>>> }
>>>>>
>>>>> void main()
>>>>> {
>>>>>   auto b = new B;
>>>>>   auto a = new A(&b.foo);
>>>>>   auto c = new C;
>>>>>   a.fitness = &c.foo; // I want this to be an error
>>>>> }
>>>>
>>>> um... did you try encapsulation?
>>>>
>>>> class A
>>>> {
>>>>    private real delegate() _dg;
>>>>
>>>>    public real dg()
>>>>    {
>>>>       return _dg();
>>>>    }
>>>>
>>>>    this(real delegate() dg) { this._dg = dg; }
>>>> }
>>>>
>>>> -Steve
>>>
>>> This was the workaround I used as well.
>>> I don't like it because of the extra level of indirection (I end up
>>> calling 2 functions instead of 1).  I don't consider this very efficient
>>> or convenient.
>>
>> I would have expected the dg() method (or property I guess) in the above 
>> to
>> be inlined, possibly requiring a final specifier? In that case I don't 
>> see
>> any reduction in performance.
>>
>> As a matter of interest the following code is fairly equivalent but 
>> results
>> in some bizarre property/delegate interaction:
>>
>> class A
>> {
>>     private real delegate() _dg;
>>
>>     this(real delegate() dg) { this._dg = dg; }
>>
>>     public real delegate() dg()
>>     {
>>         return _dg;
>>     }
>> }
>>
>> // Sample usage
>> public void example(real delegate() dg)
>> {
>>     A test = new A(dg);
>>     // test.dg        - Evaluates to the delegate dg
>>     // test.dg()     - Also evaluates to the delegate dg
>>     test.dg()()      // Required to actually execute the delegate
>> }
>>
>> Neil
>
> isn't that because you have the function (test.dg) return a "real
> delegate()" so: test.dg() returns a delegate, and test.dg()() calls that
> delegate.

Yes, however by similar logic one could conclude that because the property 
"test.dg" returns a "real delegate()" that "test.dg()" should execute the 
delegate and return a real.
February 14, 2008
Re: *final* class member (D2)
On Wed, 13 Feb 2008 10:59:26 -0500, Denton Cockburn wrote:

> How do I do this?  I'm trying to create a class member here that needs to
> be initialized in the constructor, but cannot be changed later.

The code below seems to work for me (DMD v2.008)

class A
{
  const real delegate() dg; // this is that function;

  this(const real delegate() dg) { this.dg = dg; }
}

class B
{
  real foo() { return 3.5; }
}

class C
{
  real foo() { return 4.5; }
}

void main()
{
  auto b = new B;
  auto a = new A(&b.foo);
  auto c = new C;
  a.dg = &c.foo; // correctly fails to compile.
}



-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
14/02/2008 4:13:59 PM
Next ›   Last »
1 2
Top | Discussion index | About this forum | D home