Reputation: 393
Running the program below on my computer
#include <iostream>
class Int {
public:
Int(int x) : val{x} {}
Int operator++() {
std::cout << "Int::operator++()\n";
return ++val;
}
friend Int operator+(Int a, Int b) {
std::cout << "operator+(Int, Int)\n";
return a.val + b.val;
}
friend Int operator*(Int a, Int b) {
std::cout << "operator*(Int, Int)\n";
return a.val * b.val;
}
private:
int val;
};
int main()
{
Int a = 1, b = 2;
b = ++a + b * b;
return 0;
}
I got this output:
operator*(Int, Int)
Int::operator++()
operator+(Int, Int)
As far as I known, the prefix ++
has higher precedence than binary *
. But in the output shown above, the prefix ++
is called after the binary *
! Is it because the compiler treats the operator+ as a function call (which leads to Unspecified Behavior)? Can I always consider an overloaded operator as a function (which makes the behavior of x = x++
well-defined when x
is an Int
)?
Thanks!
Upvotes: 3
Views: 88
Reputation: 48938
Is it because the compiler treats the
operator+
as a function call (which leads to Unspecified Behavior)?
Yes. But note that it doesn't matter if ++a
is evaluated after b * b
, because in the end, those two are added correctly, which respects operator precedence rules.
Your expression without the assignment is equivalent to:
operator+(a.operator++(), operator*(b, b))
The order of evaluation of function arguments is unspecified, so technically, ++a
can be evaluated before b * b
, but also the other way around.
Can I always consider an overloaded operator as a function (which makes the behavior of
x = x++
well-defined whenx
is anInt
)?
Yes and no. If Int
does the same thing as the "normal" operators would do, then no (until C++17), because that would be undefined behavior. But if Int
doesn't change x
in x++
for example, then yes.
Upvotes: 5
Reputation: 8018
As far as I known, the prefix
++
has higher precedence than binary*
.
Higher precedence doesn't mean that the prefix increment will be called before the multiplication operator, but in which order the parameters are bound to the corresponding operation.
Upvotes: 1