8

Say I have a Complex number class and operator+ is overloaded twice, both as a member function and as a global function, for example:

class Complex {
public:
    Complex operator+(const Complex& c);
};
Complex operator+(const Complex& a, const Complex& b);

And in the main function I will call the operator+ like follows:

Complex a, b;
Complex c = a + b;

Which operator+ function will be called? Thanks!

Arif Amirani
  • 26,265
  • 3
  • 33
  • 30
Brian
  • 113
  • 1
  • 7
  • possible duplicate of [Operator overloading](http://stackoverflow.com/questions/4421706/operator-overloading) – KevinDTimm Feb 27 '14 at 23:06
  • @KevinDTimm sorry i have modified the post to show what I actually did, and this code can compile fine – Brian Feb 27 '14 at 23:09
  • Operator overloading is a well defined process, answered in 1000's of places on the internet (one of which is linked above). Yours is not a new problem so it would behoove you to use existing resources rather than increasing the noise by asking the same question again. – KevinDTimm Feb 27 '14 at 23:18
  • 3
    @KevinDTimm: I don't see where the other question describes which candidate will be selected when there are both member and non-member candidates. Neither can I make sense of the relevant section of the standard, so I'd be interested to see an answer to this question. – Mike Seymour Feb 27 '14 at 23:19
  • 1
    @KevinDTimm I've done some search online actually and didn't find the answer to the exact question I had.. – Brian Feb 27 '14 at 23:23

2 Answers2

11

Members are not preferred over non-members in general, nor vice versa. C++'s overload resolution rules are applied to select one or the other.

A member function, for the purpose of overload resolution, is considered to have an implied object parameter (§13.3.1/2). So

Complex Complex::operator+(const Complex& c);

is treated as though it takes two arguments: the original const Complex& c, and another Complex& which refers to the object used to call the member function (in effect, *this).

Suppose we have two Complex variables:

Complex c1, c2;

Both c1 and c2 are non-const, so in order to call

c1.operator+(c2)

the parameter c, which is a const reference, has to bind to the non-const argument c2.

On the other hand, to call

operator+(c1, c2)

both parameters a and b, which are const references, have to bind to non-const objects, c1 and c2.

The member operator+ is better because const Complex&, Complex& is a better match for c1, c2 than const Complex&, const Complex& because it performs less qualification conversion. (§13.3.3.2/3)

If you change the declaration of the member operator+ to

Complex Complex::operator+(const Complex& c) const;

then the overload will become ambiguous, and compilation will fail.

Andrew Bate
  • 406
  • 3
  • 17
Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • So there is no priority between the two and either one could be called? thanks for the elaboration, very instructive:) – Brian Feb 27 '14 at 23:31
  • @Brian yes, exactly, it depends on more complicated factors, as I elaborated in my answer – Brian Bi Feb 27 '14 at 23:38
  • (overload resolution is one of the more complicated aspects of C++) – Brian Bi Feb 27 '14 at 23:38
  • I checked with a debugger and it was indeed the member function that had been called, the linker was just as smart as you thought it would be.. – Brian Feb 27 '14 at 23:58
  • 2
    @Brian: *smart* has nothing to do here (or the linker for what matters). There are rules in the definition of the language, and the compiler must abide by those rules. – David Rodríguez - dribeas Mar 02 '14 at 04:31
  • Thanks Brain for your informative answer. For other readers, if you declare c1, c2 as const Complex, the same rule apply but this time the non-member function is chosen instead. – mibu Jul 18 '20 at 02:24
-4

A little hint how you could find it out by yourself: Ùse the debugger to see which method is called.

acbod
  • 83
  • 5