Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Number of arguments in operator overload in C++

I'm learning C++ and I created two simple hello-world applications. In both of them I use operator overload, but here is the problem. On the first one, I can provide two arguments to overload operator, and it's fine.

Header:

enum Element {a,b,c,d,e};
Element operator + (Element x, Element y);
//more overloads for -, *, / here

Source:

Element operator + (Element x, Element y) {
    return ArrayOfElements[x][y];
}

But in my second app (simple complex number calculator) - this method didn't work. After googling and figuring out why, I end up with this code:

Header:

struct Complex {
        double Re;
        double Im;

        Complex (double R, double I) : Re(R), Im(I) { }

        Complex operator + (Complex &Number);
        //more overloads
    };

Source:

Complex Complex::operator + (Complex &Number)
    {
        Complex tmp = Complex(0, 0);
        tmp.Re = Re + Number.Re;
        tmp.Im = Im + Number.Im;
        return tmp;
    }

It's working now, but I want to know, why in the first piece of code I was allowed to put two arguments in operator overloading, but with the second one I was given the following error?

complex.cpp:5:51: error: 'Complex Complex::operator+(Complex, Complex)' must take either zero or one argument

It's the same whenever I use classes or not. I've been seeking through many docs and the second way seem to be more correct. Maybe it's because of different argument types?

Both sources compiled with -Wall -pedantic parameters using g++, both are using the same libraries.

like image 666
Lemurr Avatar asked Mar 15 '13 20:03

Lemurr


People also ask

How many arguments can be passed to an overloaded operator?

Overloading Binary Operator: In binary operator overloading function, there should be one argument to be passed. It is overloading of an operator operating on two operands.

How many operators are used for operator overloading?

Two operators = and & are already overloaded by default in C++. For example, to copy objects of the same class, we can directly use the = operator. We do not need to create an operator function. Operator overloading cannot change the precedence and associativity of operators.

How many arguments are required to overload a unary operator?

When unary operators are overloaded through a member function, they do not take any explicit arguments. But when overloaded by a friend function, they take one argument. When binary operators are overloaded through a member function they take one explicit argument.

Can we overload size of operator?

sizeof cannot be overloaded because built-in operations, such as incrementing a pointer into an array implicitly depends on it.


2 Answers

Suppose you have a class like this:

class Element {
public:
    Element(int value) : value(value) {}
    int getValue() const { return value; }
private:
    int value;
};

There are four ways to define a binary operator such as +.

  1. As a free function with access to only the public members of the class:

    // Left operand is 'a'; right is 'b'.
    Element operator+(const Element& a, const Element& b) {
        return Element(a.getValue() + b.getValue());
    }
    

    e1 + e2 == operator+(e1, e2)

  2. As a member function, with access to all members of the class:

    class Element {
    public:
        // Left operand is 'this'; right is 'other'.
        Element operator+(const Element& other) const {
            return Element(value + other.value);
        }
        // ...
    };
    

    e1 + e2 == e1.operator+(e2)

  3. As a friend function, with access to all members of the class:

    class Element {
    public:
        // Left operand is 'a'; right is 'b'.
        friend Element operator+(const Element& a, const Element& b) {
            return a.value + b.value;
        }
        // ...
    };
    

    e1 + e2 == operator+(e1, e2)

  4. As a friend function defined outside the class body—identical in behaviour to #3:

    class Element {
    public:
        friend Element operator+(const Element&, const Element&);
        // ...
    };
    
    Element operator+(const Element& a, const Element& b) {
        return a.value + b.value;
    }
    

    e1 + e2 == operator+(e1, e2)

like image 194
Jon Purdy Avatar answered Oct 03 '22 21:10

Jon Purdy


If you prefer that operator+ takes both operands as explicit arguments, it must be defined as a free (i.e. non-member) function:

class Complex {
    friend Complex operator+(const Complex& lhs, const Complex& rhs);
}

Complex operator+(const Complex& lhs, const Complex& rhs) {
    ...
}

You have to use this form if the left operand is of a primitive type, or of a class that you don't control (and thus can't add a member function to).

like image 42
NPE Avatar answered Oct 03 '22 21:10

NPE