Thread: Best practice for postfix ++ operator return type

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485

    Best practice for postfix ++ operator return type

    Hello,

    I'm overloading operator++(int) and have a question about it's return type. At the moment I'm using a temporary variable inside the function that I return after *this has been incremented.

    However, returning a copy wont work in chains, cout and so on, and returning a reference gives an error since the temp variable is local. I have solved this (for now) by declaring the temp variable static, it sort of feels like a hack, but is this ok? And if not how else can this be solved?

  2. #2
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    I wouldn't use a static. That immediately makes your code more difficult to use in a multi-threaded environment.

    Why do you say a copy wouldn't work? Seems like it would work like it should i.e. increment but return the original value. I don't see how chaining post-increments would be useful at all. Even if it was legal, it would only have the effect of a single post-increment.
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by pianorain View Post
    Why do you say a copy wouldn't work? Seems like it would work like it should i.e. increment but return the original value. I don't see how chaining post-increments would be useful at all. Even if it was legal, it would only have the effect of a single post-increment.
    It does work. But, it wont chain. Perhaps it's not that important but I've recently read that when in doubt look at how int behaves.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Subsonics
    returning a copy wont work in chains, cout and so on
    Quote Originally Posted by Subsonics
    It does work. But, it wont chain.
    Provide an example. Frankly, I do not see why you would want to chain an increment operator, and then it should work with cout.

    Quote Originally Posted by Subsonics
    Perhaps it's not that important but I've recently read that when in doubt look at how int behaves.
    You cannot chain postfix operator++ for int. Try:
    Code:
    int main()
    {
        int n = 0;
        n++++;
    }
    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

  5. #5
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by laserlight View Post
    Provide an example. Frankly, I do not see why you would want to chain an increment operator, and then it should work with cout.


    You cannot chain postfix operator++ for int. Try:
    Code:
    int main()
    {
        int n = 0;
        n++++;
    }
    Ok, but what I meant by chains here is for example:

    Code:
    int a, b, c, d = 1;
    a = b = c = d++;
    
    //or
    
    cout << a << b << c << d++;
    Edit:

    Here is an example (with static at the moment), the alternative is to remove & and static.

    Code:
            A & A::operator++(int){
                    static A tmp = *this;
                    b++;
                    updateA(b);
                    return tmp;
            }
    A holds an internal private variable b, updateA() calculates a new state for A.
    Last edited by Subsonics; 10-23-2010 at 02:36 PM.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    This works as expected:
    Code:
    #include <iostream>
    
    class myobj
    {
    public:
    	myobj operator ++ (int) { myobj tmp(*this); ++myint; return tmp; }
    	int myint;
    };
    
    int main()
    {
    	int a, b, c;
    	myobj d;
    	d.myint = 1;
    	a = b = c = (d++).myint;
    	std::cout << a << b << c << d.myint << std::endl;
    }
    Last edited by Elysia; 10-23-2010 at 04:57 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    I don't know, can it be that you are printing the int here?

  8. #8
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    >>int a, b, c, d = 1;
    >>a = b = c = d++;

    In this case all variables are assigned 1, which is d's initial value, and then the increment is performed. You are not chaining the postfix operator, but you are chaining the assignment operator.

    >>cout << a << b << c << d++;

    Again, this does not chain postfix increment. It chains the insertion operator.

    So part of your confusion I assume, is that you aren't clear on what is being chained. Chaining postfix increment operations is not allowed in C++ because it looks exactly like what laserlight showed you. If you want to do something similar to what you think that means, then you can, but you are better off writing clearer instructions. You can also increment something many times without changing the way postfix increment usually works.

    If I don't understand I apologize, but I think that simpler separate statements would be better in any case.
    Last edited by whiteflags; 10-23-2010 at 04:59 PM.

  9. #9
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Hm, ok. It might be my output operator that is broken then. I get a compile error saying there is no match for operator<< in operator++(int)(0). I thought that it needed the reference to work.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The only time it matters if you have a reference or not is if you try to modify a variable inside a function.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by whiteflags View Post
    >>int a, b, c, d = 1;
    >>a = b = c = d++;

    In this case all variables are assigned 1, which is d's initial value, and then the increment is performed. You are not chaining the postfix operator, but you are chaining the assignment operator.
    Yes, but my understanding was that for chaining in general to work, you was required to return a reference. So, if my ++ operator did not return one it would affect other operators as well.

  12. #12
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by Subsonics View Post
    Hm, ok. It might be my output operator that is broken then. I get a compile error saying there is no match for operator<< in operator++(int)(0). I thought that it needed the reference to work.
    Since you are having trouble with this error, could we see your class and the way you are using those operators?

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Subsonics View Post
    Yes, but my understanding was that for chaining in general to work, you was required to return a reference. So, if my ++ operator did not return one it would affect other operators as well.
    It really depends on how you want it to work.
    Take a file, for example.
    We could do
    Code:
    myfile >> word1 >> word2 >> word3;
    Now assuming the contents of the file is

    "Hello cruel world!"

    The question is this:
    What do you want to remain in myfile (that is, the next time you are doing an extraction operation, what do you want it to extract) after this line of code?
    Do you want it to be empty (that is, it would have reached the end of the file and can't read more)? Or do you want it to be able to read "cruel world!" later?
    You can probably see that if we return a reference to *this in the >> operator, then myfile will be end of file after the statement.
    But if we return a temporary, then myfile would contain "cruel world!" after the line (assume postfix).

    Chaining doesn't "require" any special code in that sense. All it requires is that you return something that you can apply the same operator to, again and again.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #14
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613

    >>The question is this:
    >>What do you want to remain in myfile (that is, the next time you are doing an extraction operation, what do you want it to extract) after this line of code?
    >>Do you want it to be empty (that is, it would have reached the end of the file and can't read more)? Or do you want it to be able to read "cruel world!" later?
    >>You can probably see that if we return a reference to *this in the >> operator, then myfile will be end of file after the statement.
    >>But if we return a temporary, then myfile would contain "cruel world!" after the line (assume postfix).

    This sounds more complicated than I remember.

    You chain operators on object that can use those operators. So the operator itself has to return the object in some way. References only make it clear that all the changes are happening to the same object.

    What is different here is that postfix increment introduces a side effect (the integer returned [or whatever] is not the final result but the increment is performed on the object -- this is a side effect). It so happens that the order of evaluation is defined in this particular case.

    cout << d++;

    is the same as

    cout << d;
    ++d;

    So in order to write this code correctly you need to make sure that the statement with side-effects works the same as the form without side-effects. That is the way you think about this.

    Consult your operator precedence table.

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by whiteflags View Post
    This sounds more complicated than I remember.

    You chain operators on object that can use those operators. So the operator itself has to return the object in some way. References only make it clear that all the changes are happening to the same object.
    It isn't really this complicated, but I as trying to point out how chaining works. Why sometimes you use references and why sometimes not and why it has no effect on the actual chaining, only the output.
    You can always do stuff the "wrong" way. Usually there are only two (that I know of) formally accepted ways of doing chaining, and that is pretty much postfix and prefix. The former returns a temporary and the later returns a reference to itself.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Undefined reference to.. probably Makefile problem
    By mravenca in forum C Programming
    Replies: 11
    Last Post: 10-20-2010, 04:29 AM
  2. How to pass a matrix/array from main to a function
    By Inukami in forum C Programming
    Replies: 7
    Last Post: 12-09-2009, 09:03 PM
  3. Replies: 0
    Last Post: 03-20-2008, 07:59 AM
  4. Segmentation Fault?
    By John_L in forum C Programming
    Replies: 10
    Last Post: 10-02-2007, 08:37 AM
  5. Errors
    By Rhidian in forum C Programming
    Replies: 10
    Last Post: 04-04-2005, 12:22 PM