Jump to page: 1 2
Thread overview
*final* class member (D2)
Feb 13, 2008
Denton Cockburn
Feb 13, 2008
Denton Cockburn
Feb 13, 2008
Robert Fraser
Feb 13, 2008
Robert Fraser
Feb 13, 2008
Jason House
Feb 13, 2008
Denton Cockburn
Feb 13, 2008
Simen Kjaeraas
Feb 13, 2008
Denton Cockburn
Feb 13, 2008
Neil Vice
Feb 14, 2008
Denton Cockburn
Feb 14, 2008
Neil Vice
Feb 14, 2008
Derek Parnell
February 13, 2008
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
}
February 13, 2008
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.
> 
> 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
> }

formatting issues:

(const doesn't work) real delegate() dg; // this is that
   function;

should be:

(const doesn't work) real delegate() dg; // this is that function

February 13, 2008
Denton Cockburn wrote:
> 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.
>>
>> 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
>> }
> 
> formatting issues:
> 
> (const doesn't work) real delegate() dg; // this is that
>    function;
> 
> should be:
> 
> (const doesn't work) real delegate() dg; // this is that function
> 

Use "final" :-)
February 13, 2008
Robert Fraser wrote:
> Denton Cockburn wrote:
>> 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.
>>>
>>> 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
>>> }
>>
>> formatting issues:
>>
>> (const doesn't work) real delegate() dg; // this is that
>>    function;
>>
>> should be:
>>
>> (const doesn't work) real delegate() dg; // this is that function
>>
> 
> Use "final" :-)

Oops, I thought you meant member function. AFAIK, there's no way to do that for a member variable.
February 13, 2008
"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


February 13, 2008
On Wed, 13 Feb 2008 17:07:47 +0100, Denton Cockburn <diboss@hotmail.com> wrote:

> 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.
>>
>> 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
>> }
>
> formatting issues:
>
> (const doesn't work) real delegate() dg; // this is that
>    function;
>
> should be:
>
> (const doesn't work) real delegate() dg; // this is that function
>


You could make the delegate private, and use a function to call it.

class A
{
private:
	real delegate() m_dg;
public:
	real dg()
	{
		return m_dg();
	}
	this(real delegate() _dg)
	{
		m_dg = _dg;
	}
}

Of course, private in D only means module-private, so whoever makes changes to the module might still break things, but for anyone just importing it, the problem should be gone.
February 13, 2008
Robert Fraser Wrote:

> Robert Fraser wrote:
> > Denton Cockburn wrote:
> >> 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.
> >>>
> >>> 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
> >>> }
> >>
> >> formatting issues:
> >>
> >> (const doesn't work) real delegate() dg; // this is that
> >>    function;
> >>
> >> should be:
> >>
> >> (const doesn't work) real delegate() dg; // this is that function
> >>
> > 
> > Use "final" :-)
> 
> Oops, I thought you meant member function. AFAIK, there's no way to do that for a member variable.

I thought member variables with a const storage class could be initialized in the constructor.  I thought it was possible to do stuff like:
class X{
  const int a;
  this(int b){ a = b; }
}

Am I wrong about that?  If not, why can't this apply to delegates?  Could it be confusion about return type verses const storage class?  If that's the problem, enclosing with const{} could solve the problem...
February 13, 2008
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.
February 13, 2008
On Wed, 13 Feb 2008 15:50:39 -0500, Jason House wrote:

> Robert Fraser Wrote:
> 
>> Robert Fraser wrote:
>> > Denton Cockburn wrote:
>> >> 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.
>> >>>
>> >>> 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
>> >>> }
>> >>
>> >> formatting issues:
>> >>
>> >> (const doesn't work) real delegate() dg; // this is that
>> >>    function;
>> >>
>> >> should be:
>> >>
>> >> (const doesn't work) real delegate() dg; // this is that function
>> >>
>> > 
>> > Use "final" :-)
>> 
>> Oops, I thought you meant member function. AFAIK, there's no way to do that for a member variable.
> 
> I thought member variables with a const storage class could be initialized in the constructor.  I thought it was possible to do stuff like:
> class X{
>   const int a;
>   this(int b){ a = b; }
> }
> 
> Am I wrong about that?  If not, why can't this apply to delegates?  Could it be confusion about return type verses const storage class?  If that's the problem, enclosing with const{} could solve the problem...

I would have thought I would've been able to use const as well. I got an error when I did it.

the const applies as: const(real delegate()) dg - but it doesn't affect
the ability to reassign the variable.  It gave errors when I tried to
assign it to the delegate parameter (&b.foo) because &b.foo was a real
delegate(), and not a const(real delegate()).
February 13, 2008
"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


« First   ‹ Prev
1 2