Правильный способ перегрузки бинарных реляционных операторов в C++

Каков правильный / канонический способ перегрузки бинарных реляционных операторов в C++?

Лучше использовать функции-члены, или friendбесплатные функции?

Например:

class X {
 public:
  ...

  // Use member function overloads
  bool operator==(const X& rhs) const { 
    return m_text == rhs.m_text; 
  }

 private:
  std::string m_text;
};

или же:

class X {
 public:
  ...

  // Use friend free function overloads
  friend bool operator==(const X& lhs, const X& rhs) { 
    return lhs.m_text == rhs.m_text; 
  }

 private:
  std::string m_text;
};

2 ответа

Решение

Единственное, о чем вы должны знать, это неявные преобразования.

Если ваш класс поддерживает неявные преобразования из других типов, может быть полезно сделать operator== другом для поддержки неявных преобразований в его первых аргументах.

В других случаях я полагаю, что это больше вопрос стиля.

Это не имеет большого значения, за исключением того, что

  • экземпляр X должен быть слева от оператора равенства, чтобы версия члена работала. Если ты когда-нибудь захочешь написать

    X x("hello");
    string s("hello");
    assert(s == x);
    

    вам нужен не член.

  • если вы реализуете все бинарные реляционные операторы, это потенциально большое увеличение площади поверхности вашего класса.

    Я бы вообще предпочел, чтобы этот вид вспомогательного интерфейса был отделен от логики основного класса, где это возможно (если, конечно, основной задачей вашего класса является сравнение).

    Использование не-свободных операторов и минимальный публичный интерфейс, возможно, даже лучше.

Другие вопросы по тегам