Overloading comparision operator in C++ results in “invalid operator<”

亡梦爱人 提交于 2019-11-30 14:07:11

You operator is effectively invalid.

The operator < must have a number of mathematical properties if you want it to be usable for sorting. One is the AntiSymmetry property:

x < y => !(y < x)

Let's define x = "b" and y = "aa".

  • x < y because the length of "b" is inferior to the length of "aa"
  • y < x because "aa" is inferior to "b"

Hum ?

Also note that your definition is weird for numbers in case they are prefixed by 0s.

Oh, and comparing strings is way slower than comparing numbers.

My take ? Stop altering the node with comparison information. The actual comparison mode has nothing to do within the node itself.

Then you'll just write two comparison methods, one that compares by cost and the other by origin.


And to come back to the original issue, how to write a comparator that consider ["a", "b", "aa"] sorted ?

You were almost there, but the "length" comparison is incomplete. You need to fall back to the actual lexical comparison only in the case the lengths differ, thus you forgot the case where the right hand side argument's length is inferior to the left hand side's one.

Thus the correct form is, supposing two strings:

bool compare(std::string const& lhs, std::string const& rhs) {
  if (lhs.length() < rhs.length()) { return true; }
  if (rhs.length() < lhs.length()) { return false; } // don't forget this
  return lhs < rhs;
}

Found the following code segment which was throwing the error, then thought about how my overloaded operation was working.

template<class _Ty1, class _Ty2> inline
    bool _Debug_lt(_Ty1& _Left, _Ty2& _Right,
        _Dbfile_t _File, _Dbline_t _Line)
    {   // test if _Left < _Right and operator< is strict weak ordering
    if (!(_Left < _Right))
        return (false);
    else if (_Right < _Left)
        _DEBUG_ERROR2("invalid operator<", _File, _Line);
    return (true);
    }

Working solution is this (modified again thanks to comments left by Matthieu M.)

// overloaded comparision operators
friend bool operator<(const nodeRecord & record1, const nodeRecord & record2){
    // we need to deal with strings of different lengths...
    if(record1.comparator.length() > record2.comparator.length()
        && (record1.comparator.length() !=0 && record2.comparator.length() != 0))
        return false;
    else if(record1.comparator.length() < record2.comparator.length()
        && (record1.comparator.length() !=0 && record2.comparator.length() != 0))
        return true;
    else
        return (record1.comparator < record2.comparator);
}

Thanks to everyone who helped!

Why don't you use a single comparator and make that function a little smarter? Have it check for numeric characters at the beginning, if so, do a pair of strtol() or atoi() and compare the results.

Otherwise compare the length of string and the characters as per your non-numeric requirements.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!