Reputation: 610
I have a difficulty on how this post-increment operator works for user-defined types: As I guess the Post-Increment operator operator++(T _unused)
saves the original value first (into the expression) then increment the variable. e.g:
int x{5};
int y{x++};
So x = 6
and y = 5
and that's ok.
But here is an example of user-defined:
struct s{
int x;
s(int m_) : x(m_){}
s operator++(int){ x++; return *this;}
};
int main(){
s a(0);
a.x = 7;
cout << "a::x: " << a.x << endl;
s b(a++);
cout << "a::x: " << a.x << endl; // 8
cout << "b::x: " << b.x << endl; // 8 ?!
int t = 9;
s c(t++);
cout << "c::x: " << c.x << endl; // 9
cout << "t: " << t << endl; // 10 ok
cout << endl;
return 0;
}
As you can see above: s b(a++)
will make the values of a.x
and b.x
8
? I can't understand why?
Thank you guys for your help and time and efforts.
Upvotes: 1
Views: 220
Reputation: 3911
What should you expect from: s operator++(int){ x++; return *this;}
?
You can see that x is incremented before the copy constructor constructs the temporary object. Remember returning by value invokes copy constructor. You should construct the temporary object before incrementing the variable.
In your case you can change it to look like:
s operator++(int){
return s(x++);
}
AS you can see above the temporary object is constructed with x
's value then x is incremented.
Upvotes: 0
Reputation: 11250
Change the operator to this:
s operator++(int){
s t{x++};
return t;
}
The problem is that you're defining the operator in a way that it modify this
before returning and the return is a copy of this
modified, what you need is create a new s
with the value of x
before modification and return that instead.
Upvotes: 3
Reputation: 218088
How post-increment operator works with user defined types?
The way you write it, as it is mostly a regular method.
It is good practice to avoid surprise, and so mimic behaviour of built-in types is good.
To mimic built-in type as int
, you might fix implementation to:
struct s
{
int x;
explicit s(int m_) : x(m_){}
s& operator++(){ ++x; return *this;} // pre-increment
s operator++(int){ auto res = *this; ++*this; return res;} // post-increment
};
Upvotes: 3
Reputation: 76438
You typically provide two overloads for the increment operator in a class:
class C {
public:
C& operator++(); // pre-increment
C operator++(int); // post-increment
int i;
};
The thing is, naming these "pre-increment" and "post-increment" describes how they're called, not what they do.
C c;
++c; // calls operator++()
c++; // calls operator++(int)
To implement the usual semantics of pre- and post-increment you have to write code that does the appropriate thing.
Pre-increment means incrementing the value, and returning the new value:
C& C::operator++() {
++i;
return *this;
}
Post-increment means incrementing the value and returning the old value:
C C::operator++(int) {
C res(*this);
++*this;
return res;
}
Upvotes: 2
Reputation: 385295
You don't get a post-increment just by adding int
to the function signature: you have to actually implement it!
Your code:
s operator++(int){ x++; return *this;}
This looks just like a pre-increment to me. Although it'll be called when you write someSObject++
, all it does is increment the object's own x
then return a copy of the object.
Instead, I think you meant something like:
s operator++(int)
{
S result{*this};
++(*this);
return result;
}
Or, tailored to this specific class for brevity:
s operator++(int)
{
return s{x++};
}
Upvotes: 2