Consider:
class Example
{
private:
int m_i;
public:
Example(int i) : m_i{i} {}
//Post-fix
Example operator++(int) {m_i++; return *this;}
//Pre-fix
Example& operator++() {m_i++; return *this;}
void print() const {std::cout << m_i << '\n'}
};
I was experimenting with this to determine how the compiler expanded a call to the prefix and postfix operators.
For example, when I write something like this:
Example e = 1;
e++;
I expected it to expand to something like "e.operator++(int)", or taking it a step further, I expected
e++(2);
to expand to something like "e.operator++(2).", but what I get instead is the compiler complaining about some "no match for call to '(Example) (int)'".
Next I was curious as to how "++e" mysteriously expanded into "e.operator++()", i.e. the one that returns a reference.
Playing around some more, I ended up with:
Example e = 1;
++e++;
e.print();
Which printed 2, and then:
Example e = 1;
(++e)++;
e.print();
Which printed 3.
I understand that (++e) returns a reference to the object which is then post-incremented by one, so this makes sense. I also suspect that "++e++" is giving the postfix operator precedence here (as I read in another post), so this is incrementing the temporary variable returned by the postfix operator. This too makes sense. This led me to wonder about how expressions like
++++e
++e++++
++++e++
++++e++++
are expanded (they all compile and run with expected results).
So really, what the hell is going on on the inside and how does the compiler know which operator++() to call, and how are these expressions expanded (especially in the prefix case)? What is the purpose of the placeholder variable in "operator++(int)"?