Search code examples
c++comparisoncomparison-operators

What are the default comparison operators for objects?


I found a bug in my code where I forgot to use a custom comparator when sorting a container of structs. This made me wonder what it was using as the less than operator, since I didn't define any for the struct.

How do objects compare <, >, and == when those operators aren't defined? Is it by memory address? Is it defined in the standard? I couldn't find any of this information on Google.

EDIT:

Here's the class that I was using:

using namespace std;

typedef unsigned id;

class LogEntry {
    id master_id;
    string timestamp;
    string category;
    string message;
    string str_rep;

public:
    LogEntry(id id, string t, string c, string m) :
            master_id(id), timestamp(t), category(c), message(m) {
    }

    string get_timestamp() const {
        return timestamp;
    }

    string get_category() const {
        return category;
    }

    string get_message() const {
        return message;
    }

    string to_string() {
        ostringstream ss;
        ss << master_id << "|" << timestamp << "|" << category << "|"
                << message;
        return ss.str();
    }

    id get_id() const {
        return master_id;
    }
};

EDIT2:

I realized I made a dumb mistake. I was storing a vector of pointers to the objects. Thus, it's very likely that the pointers are compared by the address. If I hadn't been storing pointers, I don't think it would have compiled.

EDIT3: KerrekSB posted a related interesting link in the comments of his answer that is related: How can pointers be totally ordered?


Solution

  • The default comparator is the standard template std::less<T>, which just uses x < y for two objects x and y of type T. There are many ways this could work:

    • T is an arithmetic, fundamental type and the built-in operator is used.

    • T is a class type and has a member operator<.

    • There is a free function operator<(T const &, T const &).

    • Your user-defined type has an implicit conversion function to a built-in type which provides a unique path for calling the built-in <.

    Additionally, it is possible to specialize std::less for your user-defined type T.