Thread: Returning a rvalue from function

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    399

    Returning a rvalue from function

    How can you force a function to return a rvalue? I thought returning something by value would do that, but apparently this returns a lvalue:

    Code:
    MyClass MyClass::operator++(int)
    {
    	MyClass old(*this);
    	++(*this);
    		
    	return old;
    }
    Would this make it into a rvalue?
    Code:
    const MyClass MyClass::operator++(int)
    {
    	MyClass old(*this);
    	++(*this);
    		
    	return old;
    }
    Last edited by Memloop; 09-22-2009 at 06:06 AM. Reason: Changed topic title

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    In this case you can't return a lvalue (returning by value always makes the result a rvalue).

    A lvalue would be a reference, for example:

    Code:
    MyClass& MyClass::operator++()
    {
        //...
        return *this;
    }
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Registered User
    Join Date
    Mar 2009
    Posts
    399
    But I can do stuff like
    Code:
    MyObj++ = AnotherObj;
    or
    Code:
    MyObj1 + MyObj2 = AnotherObj;
    despite both + and ++ return by value.

  4. #4
    The larch
    Join Date
    May 2006
    Posts
    3,573
    The general guideline with operator overloading (for numeric types) is: do as int's do. Of the following, only the last one compiles:

    Code:
    int main()
    {
        int a = 1, b = 2, c = 3;
        a + b = c; //a + b is not lvalue
        a++ = b;  //a++ is not lvalue
        ++a = b;  //++a is lvalue, but the whole expression is rather meaningless
    }
    Your examples would only compile if those operators violated that guideline and had really weird semantics.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  5. #5
    Registered User
    Join Date
    Mar 2009
    Posts
    399
    But my postfix operator looks exactly like the one above (it returns by value), and I'm still able to do those things. What's going on?

    Shouldn't this return a rvalue?

    Code:
    MyClass MyClass::operator++(int)
    {
    	MyClass old(*this);
    	++(*this);
    		
    	return old;
    }

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    What you are posting is postincrement. Its return type is MyClass. What I posted was preincrement. Its return type is MyClass&.

    Code:
    a++ = b;
    How do you think this should make sense?! Store value of a, increment a, then assign b to the stored value (what?).

    I think you should stop thinking how you can make the result of postincrement a lvalue and instead describe the situation where you need it to be a lvalue. Are you getting a compiler error for some code?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    Registered User
    Join Date
    Mar 2009
    Posts
    399
    No, I'm saying that I'm not getting any compiler errors when I do things like this with my postfix operator (code for it is above):

    Code:
    MyClassObj++ = AnotherMyClassObj;
    I want it to return a rvalue since that's what it's supposed to do, but if the code above works that means it's returning a lvalue instead.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Basically: yes, if you want to disable such syntax, then returning a const value is correct. On the other hand, there may be cases where calling a non-const member function on the result of such an operation is elegant, and there is also the consideration that such abuse of syntax is rare.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Mar 2009
    Posts
    399
    So it's impossible to return a rvalue of class type? The other arithmetic operators that I have overloaded also return by value, and I can do crazy stuff like this:

    Code:
    obj1 + obj2 = obj3;
    obj1 - obj2 = obj3;

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Memloop
    So it's impossible to return a rvalue of class type?
    I am not certain enough to say yea or nay, but frankly it does not matter whether it is a case of returning an rvalue or returning a const lvalue as long as the interface you provide to your users works the way you want it to. Personally, I just return a non-const value by default since I consider such abuse to be corner cases.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Mar 2009
    Posts
    399
    Well the code example above is nonsensical so I would prefer if it wouldn't compile at all. I'm going the const route.

  12. #12
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by Memloop View Post
    So it's impossible to return a rvalue of class type?
    No, you *are* returning an rvalue. The problem is that it's currently impossible to prevent calling the assignment operator of the rvalue that is returned. Unless you make the return type const, but as laserlight said, you might want to call a non-const function on the result directly. Also, making the return type const prevents moving from the rvalue you just returned in C++0x, and it might trip up some compilers' RVO.

    All in all, I really suggest you *don't* make it const and simply rely on the fact that silly code like 'x++ = y' is pretty easy to spot.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. why can't my perceptron learn correctly?
    By yann in forum C Programming
    Replies: 25
    Last Post: 10-15-2010, 12:26 AM
  2. unary operator overloading and classes
    By coletek in forum C++ Programming
    Replies: 9
    Last Post: 01-10-2009, 02:14 AM
  3. Smart pointer class
    By Elysia in forum C++ Programming
    Replies: 63
    Last Post: 11-03-2007, 07:05 AM
  4. Operator Overloading (Bug, or error in code?)
    By QuietWhistler in forum C++ Programming
    Replies: 2
    Last Post: 01-25-2006, 08:38 AM
  5. operator overloading and dynamic memory program
    By jlmac2001 in forum C++ Programming
    Replies: 3
    Last Post: 04-06-2003, 11:51 PM