Search code examples
c++operatorsoperator-overloadingxor

Overload power with correctly in c++?


In c++ I implemented an integer class and I overloaded operator ^ to be the power function.

integer integer::operator^ (const integer& rhs){
       return integer(pow(this->.i, rhs.i));
}

This is working correctly for two operands.

integer i1, i2, i3 ;   
 i4 = i1 ^ i2 ^ i3;  

The value of i4 is wrong mathematically because associativity required right-to-left. How can I solve this problem? How do I change associativity?

I got reasonable answers and I learn:

-We can't change  associativity or priority of an operator.   
-Good is Not to overload operators to do something conceptually different to 
 the built-in versions  
-Even compiler can't support; it hard to implement!  

Solution

  • You cannot change the associativity or priority of an operator in C++ by overloading it. These rules are hardwired into the language syntax.

    The C++ standard says (§13.5.6, emphasis mine):

    An operator function shall either be a non-static member function or be a non-member function and have at least one parameter whose type is a class, a reference to a class, an enumeration, or a reference to an enumeration. It is not possible to change the precedence, grouping, or number of operands of operators. The meaning of the operators =, (unary) &, and , (comma), predefined for each type, can be changed [...]

    Not only is the ^ operator left-associative, but it also has a very low precedence. The correct precedence for a power operator should be higher than the multiplication (so priority 4 or better on this table), but it has priority 10--this means that even additions and subtractions are evaluated before it. 1 + 2 ^ 3 * 4 will be parsed as (1 + 2) ^ (3 * 4), while a mathematically correct power operator should parse as 1 + (2 ^ 3) * 4.

    If the associativity or priority of an operator could be modified, a huge, huge syntactical mess would ensue. My humble opinion is that you should not try to overload the ^ operator to use it as a power operator. I would rather make a power method on the class.