0

I am trying to preform operator overloading in C++; for some reason the compiles keeps on giving me the error

error: ‘bool Matrix::operator==(const Matrix&, const Matrix&)’ must take exactly one argument

Now, I know that there is some way to to it with one argument using this, but I understood that by using friend I can do it this way, but it still is not working.

Here is my code,

Thanks in advance.

class Matrix{
public:
 Matrix();
 friend bool operator==(Matrix &mtrx1,Matrix &mtrx2);
 friend bool operator!=(Matrix &mtrx1,Matrix &mtrx2);

protected:
 std::vector<Cell> _matrix;
 int _row;
 int _col;

};

inline bool Matrix::operator==(const Matrix& mtrx1, const Matrix& mtrx2){

/* .......... */
}
Copas
  • 5,921
  • 5
  • 29
  • 43
bass
  • 49
  • 1
  • 2
  • 4

4 Answers4

8

The operator== member function is declared as:

class foo {
  public:
    bool operator==( foo const & rhs ) const;
};

The operator== global function is declared as:

bool operator==( foo const & lhs, foo const & rhs );

Generally, the member function is declared and defined first. Then, the global function is defined in terms of the member function as

Only one between the member function and global function is declared and defined. Having both of them is ambiguous for statements like (1) in the following

foo f1;
foo f2;
bool f1EqualsF2 = (f1 == f2 );  // (1), ambiguous

and in such cases compiler returns error. In g++, the error message looks like

equals.cpp:24: error: ambiguous overload for ‘operator==’ in ‘f1 == f2’
equals.cpp:8: note: candidates are: bool foo::operator==(const foo&) const
equals.cpp:17: note:                 bool operator==(const foo&, const foo&)

Whenever operator== is done, its recommended to do the corresponding operator!=.

Arun
  • 19,750
  • 10
  • 51
  • 60
  • 1
    Don't forget the const on the method operator==() – Martin York Sep 21 '10 at 05:43
  • 2
    This is wrong. Generally you either define a member function _or_ you define a free function. You shouldn't define both otherwise `a == b` will generally be ambiguous. A free function is usually preferred as it leads to consistent implicit conversion rules for both left and right operands. As it stands you can't do `lhs.operator==( rhs )` as `operator==` is a non-`const` member function and is `private` in `foo`. – CB Bailey Sep 21 '10 at 06:41
  • Thanks to Martin York and Charles Bailey (+1 to them); I made some corrections in the answer (added `const` in member function, and `public` qualifier). – Arun Sep 21 '10 at 14:42
  • You've edited, but you have still left in the suggestion that you have both a member `operator==` and a global `operator==` (one implemented in terms of the other). This is not correct because it will make `a == b` ambiguous where `a` and `b` are both `foo`. – CB Bailey Sep 21 '10 at 15:16
5

Although you've put the friend declaration inside the class, it's not a member. So the function definition should be a non-member:

inline bool operator==(const Matrix& mtrx1, const Matrix& mtrx2) {...}

You also need to add const qualifiers to the arguments of the declarations, to match those in the definition.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
  • 1
    Note, however, that the `friend` declaration forces it to be a non-member, so even if you define it in-place inside the class definition, it'll really be a global function! – Jerry Coffin Sep 20 '10 at 23:19
  • 1
    @Jerry Coffin: or, more strictly, a function belonging to the innermost namespace enclosing the given class. – CB Bailey Sep 21 '10 at 07:25
3
class Matrix{
public:
    Matrix();
    friend bool operator==(const Matrix &mtrx1, const Matrix &mtrx2);
    friend bool operator!=(const Matrix &mtrx1, const Matrix &mtrx2);

protected:
    std::vector<Cell> _matrix;
    int _row;
    int _col;
};

inline bool operator==(const Matrix& mtrx1, const Matrix& mtrx2){
    /* .......... */
    return true;
}

Pass compilation in Visual Studio 2005.

  1. omit the const qualifier in your friend declaration

  2. don't need Matrix:: in operation== definition

Yuncy
  • 761
  • 1
  • 9
  • 20
1

You do it with 2 parameters if you are doing it outside of the class, not as a member function.

As a member function you need only 1 parameter (the other parameter is *this)

Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636