小于运算符不能作为成员函数重载。

4
我希望在一个 map 中将我的 class 作为 key,因此我重载了 operator+。如果我将其重载为友元函数,则可以正常工作。但是,如果我在类内部将其重载为成员函数,则会导致编译错误。
具体而言,这段代码无法编译,并生成编译错误:
Syl.h
bool operator< (const Syl& rhs);

Syl.cpp

bool Syl::operator< (const Syl& rhs) {  return false; }

当这段代码编译时,

Syl.h

friend bool operator< (const Syl& lhs, const Syl& rhs);

Syl.cpp

bool operator< (const Syl& lhs, const Syl& rhs) {   return false; }

我不知道为什么。我知道operator<是二元的,但有没有办法将其作为函数成员进行重载?


1
由于重载解析和隐式转换的工作方式,friend版本无论如何都是更好的选择。 - Sebastian Redl
友好版本指定了两个操作数都为const,而另一个版本仅表示输入参数为const。您必须将该方法标记为const... 您必须仔细阅读错误信息,特别注意诸如constsigned等单词的含义。 - Kupto
2个回答

3

通常,像operator<这样的成员运算符不会修改它们所操作的对象。如果是这种情况,您需要在声明末尾加上关键字const来指定该方法为常量。

class Syl {
  ...
  public:
  bool operator<(const Syl& rhs) const;  
}

这样的运算符可以与STL容器(例如std::map)一起使用。


将当前版本的成员运算符翻译为独立运算符后,将如下所示:

friend bool operator<(Syl& lhs, const Syl& rhs);

请注意,lhs缺少const。这在本质上仍然是正确的,但不典型。您需要提供一个左值作为lhs。如果您提供其他内容,则会得到“未找到运算符…”错误。STL的std::map也不希望出现这种情况,因此您的错误可能来自于标准头文件,在模板实现中深处。

1
因此,编译时错误并不是由于他声明了重载运算符的方式,而是由于成员重载运算符用于对只接受重载 < 运算符的映射进行排序,如果其两个参数都是 const,则会出现这种情况。 - user
是的,那正是它。 - Sebastian Redl
是的 - 运算符不需要是 const。一些通常不是(例如,operator=),而有些则通常是。请注意,非 const 运算符需要 lvalue 作为左侧参数,如果您未提供,则会获得类似的错误提示。 - CygnusX1
非常感谢您提供如此详细的解释。 - Tris

2
假设ab都是Syl类型,如果aconst,则你的第一个成员形式在表达式a < b中无效,并且会导致编译错误。
为了解决这个问题,你需要将成员operator<()指定为:
bool operator< (const Syl& rhs) const;    // note the trailing const

没有那个末尾的const,在表达式a < b中,a不能是const(即operator<()被允许更改它)。
您的第二种形式是正确的,因为它指定了两个操作数都是const引用。
<这样的比较运算符通常不会改变任何一个操作数。 const限定符传达了这一事实。
请记住,您可以提供成员形式或非成员形式。提供两者都会导致歧义错误(当编译器看到类似于a < b的表达式时,它没有基础来优先选择其中一个)。

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