在C++中正确地重载二元关系运算符的方法

3

在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;
};

也许这个问题可以帮到你:这里 - Rakete1111
2个回答

4
它并没有太大的区别,除了...
  • an instance of X needs to be on the left-hand-side of the equality operator for the member version to work. If you ever want to write

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

    you need a non-member.

  • if you're implementing all the binary relational operators, that's a potentially large increase in your class's surface area.

    I'd generally prefer this kind of auxiliary interface to be kept apart from the main class logic where possible (unless, of course, your class's primary concern is comparison).

    Using non-friend free operators and a minimal public interface is perhaps even better.


3

你需要注意的一件事是隐式转换。

如果你的类支持来自其他类型的隐式转换,那么使operator==成为友元以支持其第一个参数上的隐式转换可能很有用。

在其他情况下,我认为这更多是风格问题。


请纠正我,但即使是成员运算符也会发生隐式转换。 - Bruno Ferreira
1
@BrunoFerreira 基本上,只有在参数列表中列出的参数才有资格进行隐式转换,但是当 operator== 是成员函数时,第一个参数是 this,它不符合隐式转换的条件。 - Edgar Rokjān
当然。我创建了一个小的测试案例,如果我删除对int的隐式转换,它就会失败。 - Bruno Ferreira
经过深思熟虑,成员函数是__thiscall,这意味着它有一个隐式的this作为第一个参数。在我的测试案例中,应该是类似于bool operator==(A* this, int x)的形式。根据C++标准,第一个参数是左侧,第二个参数是右侧。 - Bruno Ferreira

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接