Что имеет приоритет, оператор свободной функции == () или оператор функции-члена == ()? - PullRequest
1 голос
/ 25 октября 2019

Когда определены свободная операторная функция и операторная функция-член, какая из них используется для сравнения?

#include <iostream>

class A;
class B;

bool operator==(const A &a, const B &b){ return true; };

class A
{
  public:
      bool operator==( const B &rhs ){ return false; };
};

class B
{
};

int main( int argc, char **argv )
{
  A a;
  B b;
  if( a == b )
  { 
      std::cout << "a==b" << std::endl;
  }
};

Я выполнил код пару раз, и кажется, что оператор-член победил. Это всегда так?

Ответы [ 2 ]

5 голосов
/ 25 октября 2019

Я выполнил код пару раз, и кажется, что оператор участника выиграл.

Да, участник выигрывает в вашем примере. Но не по той причине, вы думаете.

Функции-члены имеют неявный параметр объекта (на что указывает this), а тип параметра объекта определяется cv-квалификаторами в конце функции-члена. В этом случае у вашего оператора-члена нет cv-квалификаторов, поэтому тип неявного объекта просто A.

По сути, у нас есть два кандидата:

bool operator==(A const&, B const&); // your non-member operator
bool operator==(A&,       B const&); // your member operator

Членоператор является лучшим соответствием, потому что первый параметр является лучшим соответствием - нам не нужно брать более константную ссылку на a.

Если вы сделали свой оператор const (как выв общем случае), тогда у нас были бы два кандидата:

bool operator==(A const&, B const&); // your non-member operator
bool operator==(A const&, B const&); // better member operator

, которые идентичны, нет причин отдавать предпочтение одному другому, и мы получили бы двусмысленность. Не существует правила предпочитать члена функции, не являющейся членом (или наоборот).

2 голосов
/ 25 октября 2019

Вы объявляете 1-й тип параметра как const & в операторе, не являющемся членом. Затем с учетом a == b для вызова оператора, не являющегося членом, a необходимо преобразовать в const. С другой стороны, оператор-член объявлен как неконстантный, тогда его операндом является неконстантный A, тогда это точное совпадение и выигрывает в разрешении перегрузки.

Если вы измените 1-й тип параметране являющийся членом оператора A& вы получите ошибку неоднозначности. LIVE

Или квалифицируйте оператора-участника как const, вы также получите ошибку неоднозначности. ЖИВОЙ

...