Thread overview
What should opAssign return?
Oct 23, 2007
Charles D Hixson
Oct 23, 2007
Nathan Reed
Oct 23, 2007
Charles D Hixson
Oct 23, 2007
Rioshin an'Harthen
Oct 23, 2007
BCS
Re: What should opAssign return, finally answered!
Oct 23, 2007
downs
Oct 23, 2007
Charles D Hixson
October 23, 2007
What I would expect is:

class A
{
  A opAssign(A a)
  {
     // do stuff here
     return this;
  }
}

but the only examples that I can find (variant.d) return *this ... which leaves me quite confused.  Is this something special that Variant is doing to allow it to handle multiple types (I didn't follow the internals), or do I have what is supposed to be returned wrong?
October 23, 2007
Charles D Hixson wrote:
> What I would expect is:
> 
> class A
> {
>   A opAssign(A a)
>   {
>      // do stuff here
>      return this;
>   }
> }
> 
> but the only examples that I can find (variant.d) return *this ... which leaves me quite confused.  Is this something special that Variant is doing to allow it to handle multiple types (I didn't follow the internals), or do I have what is supposed to be returned wrong?

'this' is a pointer to the object, so '*this' is (a reference to) the actual object.

Thanks,
Nathan Reed
October 23, 2007
Nathan Reed wrote:
> Charles D Hixson wrote:
>> What I would expect is:
>>
>> class A
>> {
>>   A opAssign(A a)
>>   {
>>      // do stuff here
>>      return this;
>>   }
>> }
>>
>> but the only examples that I can find (variant.d) return *this ... which leaves me quite confused.  Is this something special that Variant is doing to allow it to handle multiple types (I didn't follow the internals), or do I have what is supposed to be returned wrong?
> 
> 'this' is a pointer to the object, so '*this' is (a reference to) the actual object.
> 
> Thanks,
> Nathan Reed

Sorry, I'm sure you think you answered the question, but I'm as confused as before.

Are you saying that *this is the correct thing to return?
(I know that "*this" means a pointer to this, and that "this" is a pointer to the object being created, but that doesn't help me at the point where I am confused.  I still don't know what should be returned.)
October 23, 2007
"Charles D Hixson" <charleshixsn@earthlink.net> kirjoitti viestissä news:ffk5i4$2led$1@digitalmars.com...
> Nathan Reed wrote:
>> Charles D Hixson wrote:
>>> What I would expect is:
>>>
>>> class A
>>> {
>>>   A opAssign(A a)
>>>   {
>>>      // do stuff here
>>>      return this;
>>>   }
>>> }
>>>
>>> but the only examples that I can find (variant.d) return *this ... which leaves me quite confused.  Is this something special that Variant is doing to allow it to handle multiple types (I didn't follow the internals), or do I have what is supposed to be returned wrong?
>>
>> 'this' is a pointer to the object, so '*this' is (a reference to) the actual object.
>>
>> Thanks,
>> Nathan Reed
>
> Sorry, I'm sure you think you answered the question, but I'm as confused as before.
>
> Are you saying that *this is the correct thing to return?
> (I know that "*this" means a pointer to this, and that "this" is a pointer to the object being created, but that doesn't help me at the point where I am confused.  I still don't know what should be returned.)

this is a pointer to the object, and the unary asterisk (*) is the dereferencing operator. Thus, say you have something like

   int nInt = 42;
   int* pInt = &nInt;
   writeln(*pInt);

, then nInt gets the value 42, the pointer pInt gets the address of nInt and the call to writeln dereferences the pointer, printing 42.

To take this back to the *this, the dereferencing operator in front of the this pointer dereferences the pointer, returning the actual object the this pointer is pointing to.

To reiterate: this is a pointer to the object being created, while *this is the actual object being created. Let's say the type of the object is A, as you had above. Now, this is the same as A*, and *this, which dereferences the pointer so that the actual object is visible, has the type A.

In comparison with C, let's say you have a pointer to a B:

   typedef struct _B
   {
       int value;
   } B;
   B* pB;

Now you can access the member 'value' with

   B->value

or equally with

   (*B).value

where -> is a dereferencing member access and . is a normal member access. The * before the B again does the dereferencing, so -> is basically a shorthand notation.

However, compared to C, D automatically dereferences a pointer when accessing its' members; this, however, doesn't happen when returning an object type, so in the original example

   class A
   {
       A opAssign(A a)
       {
           return this;
       }
   }

the return statement is trying to return a pointer to A, when the method signature says to return an A. Thus the dereferencing in variant.d, so that the return statement returns *this instead. 

October 23, 2007
Charles D Hixson wrote:
> What I would expect is:
> 
> class A
> {
>   A opAssign(A a)
>   {
>      // do stuff here
>      return this;
>   }
> }
> 
> but the only examples that I can find (variant.d) return *this ... which leaves me quite confused.  Is this something special that Variant is doing to allow it to handle multiple types (I didn't follow the internals), or do I have what is supposed to be returned wrong?
Variant is a struct.
The this of a struct is a pointer.
Ergo it has to dereference it, since opAssign returns the assignee for
purposes of assignment chaining (a=b=c).

Hope that clears things up.
 --downs
October 23, 2007
"downs" <default_357-line@yahoo.de> wrote in message news:ffkf66$6cr$1@digitalmars.com...
> Charles D Hixson wrote:
>> What I would expect is:
>>
>> class A
>> {
>>   A opAssign(A a)
>>   {
>>      // do stuff here
>>      return this;
>>   }
>> }
>>
>> but the only examples that I can find (variant.d) return *this ... which leaves me quite confused.  Is this something special that Variant is doing to allow it to handle multiple types (I didn't follow the internals), or do I have what is supposed to be returned wrong?
> Variant is a struct.
> The this of a struct is a pointer.
> Ergo it has to dereference it, since opAssign returns the assignee for
> purposes of assignment chaining (a=b=c).
>
> Hope that clears things up.
> --downs

To take it one step further, what you have is correct for classes, what Variant has is correct for structures.  The this member (which strangely, I can't find the documentation for on digital mars' site) is a reference for a class, and is a pointer for a struct.  Since the return value for opAssign on a class is a reference, you return this.  Since the return value for opAssign is a struct, not a pointer to a struct, you must return *this.

-Steve


October 23, 2007
Reply to Rioshin an'Harthen,

> class A
> {
> A opAssign(A a)
> {
> return this;
> }
> }
> the return statement is trying to return a pointer to A, when the
> method signature says to return an A. Thus the dereferencing in
> variant.d, so that the return statement returns *this instead.
> 

fails: the type A is already a pointer to an object (because it is a class) so the type of "this" is "A" not "A*".


October 23, 2007
downs wrote:
> Charles D Hixson wrote:
>> What I would expect is:
>>
>> class A
>> {
>>   A opAssign(A a)
>>   {
>>      // do stuff here
>>      return this;
>>   }
>> }
>>
>> but the only examples that I can find (variant.d) return *this ... which
>> leaves me quite confused.  Is this something special that Variant is
>> doing to allow it to handle multiple types (I didn't follow the
>> internals), or do I have what is supposed to be returned wrong?
> Variant is a struct.
> The this of a struct is a pointer.
> Ergo it has to dereference it, since opAssign returns the assignee for
> purposes of assignment chaining (a=b=c).
> 
> Hope that clears things up.
>  --downs
Thank you.  Yes, that explains my confusion.