CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Jul 2005
    Posts
    1,030

    A question regarding operator = overloading

    Here is a code snippet,

    Code:
    class aInt
    {
    public:
    	aInt()
    	{
    		data = 0;
    	}
    
    	aInt operator=(const int& x)
    	{
    		data = x;
    		return *this;
    	}
    	
    private:
    	int data;
    };
    
    
    int main()
    {
    	aInt x, y, z;
    
    	(x = y) = z = 3;
    
    	return 0;
    }
    Take a look at the definition of operator=. It returns aInt instead of aInt&. Using (x=y)=z is fine. But my understanding is that if you want to support (x=y)=z, operator= must return reference to be quailifed as left hand operand. So I expect this code will have compiler error. Any idea why I am wrong?

  2. #2
    Join Date
    Jan 2006
    Location
    Belo Horizonte, Brazil
    Posts
    405

    Re: A question regarding operator = overloading

    The code is correctly compiling. But there a few details that might generate some confusion.

    First, you are overloading operator=(int const&), which is only called for the z = 3 statement. However, anyway the code would still be legal because you return a simple copy from operator=(int const&). The copy would not be assignable if you had declared it as const, for example:

    Code:
    class aInt
    {
    public:
      aInt const operator=(int const& x) { /* ... */ }
      
      //...
    };
    
    int main()
    {
      //...
      (x = 6) = 3; //Non-sense, just for the example.
    
      return 0;
    }
    Back to the expression in your example, notice that when assigning only among x, y, and z, you are really invoking a version of operator= which you did not defined in your class. This is operator=(aInt const&). See that the parameter is aInt instead of int?

    Then, the assignments you mentioned (x = y) = z would compile depending on what you specify as the return type. Usually, this is a reference or a reference-to-const, the one the better fits your needs. If you choose to return a reference-to-const the (x = y) = z would not work, as you expect.

    Code:
    class aInt
    {
    public:
      aInt const& operator=(aInt const& x)
      {
        data = x.data;
        return *this;
      }
      //...
    };
    If you want the cascading assignments to work just remove the const from the returned reference.

    As a final note: Prefer to use the constructor initialization list instead of assignments inside the constructor body.

  3. #3
    Join Date
    Jul 2005
    Posts
    1,030

    Re: A question regarding operator = overloading

    Thanks for your response! But I still have questions. The following is the revised code snippet. This time I modified the definition of operator =. This time (x=y)=z is still legal. But I thought operator= returns aInt, so x=y would return aInt which is not a lvalue. How come (x=y)=z is legal since x=y expects to return a lvalue.
    Code:
    class aInt
    {
    public:
    	aInt()
    	{
    		data = 0;
    	}
    
    	aInt operator=(const aInt& x)
    	{
    		data = x.data;
    		return *this;
    	}
    	
    private:
    	int data;
    };
    
    
    int main()
    {
    	aInt x, y, z;
    
    	(x = y) = z;
    
    	return 0;
    }
    Quote Originally Posted by ltcmelo View Post
    The code is correctly compiling. But there a few details that might generate some confusion.

    First, you are overloading operator=(int const&), which is only called for the z = 3 statement. However, anyway the code would still be legal because you return a simple copy from operator=(int const&). The copy would not be assignable if you had declared it as const, for example:

    Code:
    class aInt
    {
    public:
      aInt const operator=(int const& x) { /* ... */ }
      
      //...
    };
    
    int main()
    {
      //...
      (x = 6) = 3; //Non-sense, just for the example.
    
      return 0;
    }
    Back to the expression in your example, notice that when assigning only among x, y, and z, you are really invoking a version of operator= which you did not defined in your class. This is operator=(aInt const&). See that the parameter is aInt instead of int?

    Then, the assignments you mentioned (x = y) = z would compile depending on what you specify as the return type. Usually, this is a reference or a reference-to-const, the one the better fits your needs. If you choose to return a reference-to-const the (x = y) = z would not work, as you expect.

    Code:
    class aInt
    {
    public:
      aInt const& operator=(aInt const& x)
      {
        data = x.data;
        return *this;
      }
      //...
    };
    If you want the cascading assignments to work just remove the const from the returned reference.

    As a final note: Prefer to use the constructor initialization list instead of assignments inside the constructor body.

  4. #4
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: A question regarding operator = overloading

    Quote Originally Posted by LarryChen
    How come (x=y)=z is legal since x=y expects to return a lvalue.
    Member functions like the copy assignment operator can be called with such temporaries (they can be passed as arguments, after all). This is sometimes useful, though in this case it is not.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  5. #5
    Join Date
    Jul 2005
    Posts
    1,030

    Re: A question regarding operator = overloading

    No, my question is why (x=y) can be a lvalue since operator = return by value not by reference? Does my question make any sense?
    Quote Originally Posted by laserlight View Post
    Member functions like the copy assignment operator can be called with such temporaries (they can be passed as arguments, after all). This is sometimes useful, though in this case it is not.

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: A question regarding operator = overloading

    Quote Originally Posted by LarryChen View Post
    No, my question is why (x=y) can be a lvalue
    Code:
    (x=y)=z;
    Don't focus on l-value and look at the entire line in context, up until the terminating semicolon (i.e. the sequence point).

    The (x=y) returns an aInt object. Then you are assigning another object, z, to this object. Then you have the terminating semicolon -- statement is over. So where is the conclusion that

    Code:
    (x=y)=z;
    won't work?

    If operator = returned a const object, then you can't assign.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; February 12th, 2010 at 01:32 AM.

  7. #7
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: A question regarding operator = overloading

    Quote Originally Posted by LarryChen
    No, my question is why (x=y) can be a lvalue since operator = return by value not by reference? Does my question make any sense?
    It does not make any sense when you recognise that it is a member function, not a built-in assignment operator, that is invoked. Let's write that expression in another way:
    Code:
    x.operator=(y).operator=(z);
    Now, let us generalise the expression for some member function foo:
    Code:
    x.foo(y).foo(z);
    What does it mean now if the result of x.foo(y) is not an lvalue? Does it mean that you cannot call member function foo with argument z on the result?
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  8. #8
    Join Date
    Jul 2005
    Posts
    1,030

    Re: A question regarding operator = overloading

    Thanks so much for your help. Now I understand why my question doesn't make sense.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured