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

しかしsort()vectorwithWordEntryオブジェクトを呼び出すと、エラー メッセージが表示されます。

二項式の無効なオペランド ('const WordEntry' および 'const WordEntry')

そして、それは を指していstl_algo.hます。

ここで何が起こっているか知っている人はいますか?

4

3 に答える 3

7

現在、への引数<は const ですが、メンバーはそうではありません。これは、にバインドできないため<、2 つのオブジェクト間の比較が失敗することを意味します。メンバーと引数の両方を作成する必要がありますconst WordEntry&<const

bool operator<(const WordEntry& otherWordEntry) const;

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

注:コメントで指摘されているように、WordEntry参照渡しも必要です

于 2012-04-19T18:44:26.450 に答える
2
string WordEntry::getWord()
bool WordEntry::operator<(WordEntry otherWordEntry)
{
   return  lexicographical_compare(_word.begin(),
                                   _word.end(),
                                   otherWordEntry.getWord().begin(),
                                   otherWordEntry.getWord().end());
}

getWordメンバー関数は、内部メンバー属性のコピーを作成し、そのコピーを返します。を 2 回連続して呼び出すと、同じ内容のgetWord2 つの異なるインスタンスが返されstd::stringますが、それらは異なるオブジェクトであることに変わりはありません。このlexicographical_compare関数では、1 番目と 2 番目の引数が同じコンテナーへの反復子である必要があり、同様に 3 番目と 4 番目の引数も必要です。あなたの場合、イテレータを別のコンテナー (文字列) に渡しています。これは関数内で比較され、未定義の動作が発生します。

最も簡単な解決策は、 internal への参照をgetWord返すことです。これにより、イテレータは両方とも右側のオブジェクトの internal オブジェクトを参照します。conststd::string

他の人も言及しているように、コードを改善WordEntryするには、をconst参照渡しし、を渡すoperator<必要があります。ただし、実装の問題は、異なるコンテナーのイテレーターが混在していることです。const

于 2012-04-19T18:58:48.437 に答える
2

右辺値に const 参照を使用し、メソッド const を作成して、オブジェクトを変更しないことをコンパイラーに約束します。

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

また、オペレーターを明示的に呼び出す必要もありません。オブジェクトに対して定義したら、次のWordEntryことができます。

if (w1 < w2) { // etc }

カスタム比較述語を使用していないため、次を使用できますstd::string::operator<

return _word < otherWordEntry._word;

David は、内部メンバーを値で返すことについて優れた点を指摘しています。lexicographical_compareメンバーの代わりにアクセサーを直接使用する場合_word(クラス スコープにいる場合は可能です)、次のように定義する必要があります。

const string& getWord() const { return _word; }
于 2012-04-19T18:45:03.857 に答える