C++运算符<重载

4

我遇到了<运算符过载的问题。 我有这个类:

WordEntry.h:

class WordEntry
{
public:
    WordEntry(string word);
    ~WordEntry();

    bool operator<(const WordEntry otherWordEntry);

    string getWord();

private:
    string _word;
};

WordEntry.cpp(我已经去掉了构造函数和析构函数):

string WordEntry::getWord()
{
   return _word;
}


bool WordEntry::operator<(WordEntry otherWordEntry)
{
   return  lexicographical_compare(_word.begin(),_word.end(),otherWordEntry.getWord().begin(),otherWordEntry.getWord().end());
}

当我像这样在main.cpp中使用时,一切都很顺利:

    WordEntry w1("Der");
    WordEntry w2("das");

    if (w1.operator<(w2)) {
       cout << "w1 > w2";
    }
    else 
    {
       cout << "w2 > w1";
    }

但是,当我对包含WordEntry对象的vector调用sort()时,会出现错误消息:

二进制表达式的操作数无效('const WordEntry'和'const WordEntry')

并且它指向stl_algo.h

有人知道这里发生了什么吗?


const 的复制基本上是毫无意义的... - AJG85
3个回答

7

目前<的参数是常量,但成员不是。这意味着两个const WordEntry&对象之间的<比较将失败,因为它无法绑定到<。您需要使成员和参数都是const

bool operator<(const WordEntry& otherWordEntry) const;

bool WordEntry::operator<(const WordEntry& otherWordEntry) const {
  ...
}

注意:如评论所指出,您还应通过引用传递WordEntry

1
@LeonS:请注意,您的代码仍存在未定义的行为。虽然它似乎可以工作,但如果您将一个字符串与一个子字符串进行比较,例如以正确的顺序比较“Hello”和“Hell”(WordEntry("Hello").operator<(WordEntry("Hell"))),您可能会发现应用程序有时会崩溃。 - David Rodríguez - dribeas

2

使用const引用来处理右值,并将方法声明为const,以保证编译器不会更改对象。

bool operator<(const WordEntry& otherWordEntry) const
{
    // comparison
}

您也不需要显式调用运算符。一旦为WordEntry对象定义,您可以这样做:

if (w1 < w2) { // etc }

如果您没有使用自定义比较谓词,您可以直接使用 std::string::operator<

return _word < otherWordEntry._word;

David 指出了一个很好的观点,即通过值返回内部成员。如果你想使用访问器而不是直接使用 _word 成员(因为你在类作用域中),来使用 lexicographical_compare,那么你应该这样定义:

const string& getWord() const { return _word; }

2
string WordEntry::getWord()
bool WordEntry::operator<(WordEntry otherWordEntry)
{
   return  lexicographical_compare(_word.begin(),
                                   _word.end(),
                                   otherWordEntry.getWord().begin(),
                                   otherWordEntry.getWord().end());
}
getWord成员函数创建内部成员属性的副本并返回该副本。连续两次调用getWord将返回两个不同的std::string实例,其内容相同,但它们仍然是不同的对象。 lexicographical_compare函数要求第一个和第二个参数是指向同一容器的迭代器,同样第三个和第四个参数也是如此。在您的情况下,您正在传递到不同容器(字符串)中的迭代器,这些迭代器将在函数内部进行比较,并产生未定义的行为。
最简单的解决方案是使getWord返回对内部std::stringconst引用,以便迭代器都引用右侧对象中的内部对象。
正如其他人也提到的,您应该通过const引用传递WordEntry,并且operator<应该是const,以改进代码。但是,在您的实现中问题在于混合了来自不同容器的迭代器。

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