Почему мне нужно, чтобы этот оператор non friend == перегружал функцию-член, чтобы избежать ошибок «неопределенной ссылки»?

#c #operator-overloading #undefined-reference #linkage

#c #перегрузка оператора #неопределенная ссылка #связь

Вопрос:

У меня есть следующий класс, он определен следующим образом:

 namespace ns{
class Bit{
public:
    explicit Bit(bool bit);
    Bit() = default;
    explicit operator bool () const;
    [[nodiscard]]
    bool value() const;
    [[nodiscard]]
    Bit operator==(const Bitamp; rhs) const;
    //friend Bit operator==(const Bit amp;lhs, const Bit amp;rhs); also doesn't work
private:
    bool m_bit;
};
//doesn't work
//[[nodiscard]]
//Bit operator==(const Bit amp;lhs, const Bit amp;rhs);
}
 

Когда я определяю operator == overload как отдельную функцию, это не работает, я получаю

 undefined reference to `ns::operator==(ns::Bit constamp;, ns::Bit constamp;)'
 

Аналогичная история для версии функции друга.

Определение автономной функции в файле .cpp выглядит следующим образом:

 ns::Bit operator==(const ns::Bit amp;lhs, const ns::Bit amp;rhs) {
    return ns::Bit(lhs.value() == rhs.value());
}
 

Определение функции-члена, которая работает, выглядит следующим образом

 ns::Bit ns::Bit::operator==(const ns::Bit amp;rhs) const{
    return Bit(value() == rhs.value());
}
 

Почему меня заставляют создавать функцию-член?

Комментарии:

1. Вы создаете прототип ns::operator== (в пространстве имен ns), но определяете ::operator== (глобальное пространство имен).

2. Что означает «не работает»? переключив его на вашу версию «не работает», он компилируется для меня и int main() { ns::Bit a,b; if(a==b) return 1; return 0;} хочет вызвать функцию friend.

3. @jhill прочитал мой пост, в нем говорится, почему он не работает, 1201ProgramAlarm все правильно. Если вы попробовали код, который я использовал, он не должен работать для вас (возможно, вы определяете оператор в глобальном пространстве имен?

4. @1201ProgramAlarm Хорошо, вау, это именно так, моя IDE обычно исправляет подобные вещи, но, по-видимому, плохо обрабатывает автоматическую генерацию определений автономных операторов. Если вы напишете ответ, описывающий, в чем проблема, я бы с удовольствием пометил его как правильный и поддержал.

Ответ №1:

 ns::Bit ns::operator==(const ns::Bit amp;lhs, const ns::Bit amp;rhs) {
  return ns::Bit(lhs.value() == rhs.value());
}
 

вы создали прототип ns::operator== , а затем определили ::operator== .

ns::operator== Найдено только через ADL. ::operator== также может быть найдено в зависимости от того, какие другие == операторы и в каком пространстве имен вы находитесь, что добавляет путаницы.

Комментарии:

1. В качестве альтернативы: namespace ns { Bit operator==(const Bit amp;lhs, const Bit amp;rhs) { return Bit(lhs.value() == rhs.value()); } }