Opérateurs de relation

    Les quatre opérateurs de relation sont <, <=> et >=. Ils renvoient true ou false. Le type du résultat est bool. Les opérandes doivent être de types arithmétiques, énumératifs ou pointeurs. Pour les deux premiers types, les règles de comparaison sont celles de l'arithmétique. Les règles qui régissent la comparaison de pointeurs sont précisément décrites dans la norme ISO du C++ : 5.9 Relational operators.

Surcharge des opérateurs de relation

    La surcharge de ces opérateurs dans une classe dote cette dernière d'une relation d'ordre. Une telle classe est dite LessThan Comparable dans la documentation SGI de la bibliothèque standard du C++. Certains algorithmes génériques de la bibliothèque (sort(), par exemple), ne sont utilisable que sur des conteneurs d'objets dont le type a cette propriété.

    Le listing ci-dessous illustre la surcharge de l'opérateur < d'une classe CPoint, représentant un point de coordonnées x et y dans un plan. La relation d'ordre est établie par rapport à la distance du point à l'origine : un point est considéré comme "inférieur" à un autre s'il est plus près de l'origine :
 
class CPoint
{
    int m_X;
    int m_Y;

  public :
    // ...
    bool operator < (const CPoint & P) throw ()
    {
        return (m_X * m_X + m_Y * m_Y) < (P.m_X * P.m_X + P.m_Y * P.m_Y);

    } // operator <

}; // CPoint

Opérateurs de relation génériques

    Pour doter une classe d'une relation d'ordre, il n'est pas nécessaire qu'elle possède une surcharge des quatre opérateurs de relation. Seul l'opérateur < est nécessaire, des définitions génériques des autres sont disponibles dans la bibliothèque [1], dans le sous-espace de noms rel_ops de l'espace de noms standard std. Leur utilisation nécessite l'inclusion du fichier <utility> qui contient les déclarations suivantes :
 
namespace std {
    namespace rel_ops {
        template <class T> bool operator >  (const T&, const T&);
        template <class T> bool operator <= (const T&, const T&);
        template <class T> bool operator >= (const T&, const T&);
    }
}

    Les définitions correspondantes peuvent être :
 
template <class T>
inline bool std::rel_ops operator > (const T& a, const T& b)
{
    return b < a;
}
template <class T>
inline bool std::rel_ops operator <= (const T& a, const T& b)
{
    return !(b < a);
}
template <class T>
inline bool std::rel_ops operator >=(const T& a, const T& b)
{
    return !(a < b);
}

Opérateurs d'égalité

    Les deux opérateurs de relation sont == et !=. Ils ont la même sémantique que les opérateurs de relation décrits ci-dessus. Les règles qui régissent la comparaison de pointeurs sont précisément décrites dans la norme ISO du C++ : 5.10 Equality operators. Cependant, ils ont une priorité inférieure aux opérateurs de relation, et la relation a < b == c < d est interprétée comme (a < b) == (c < d).

Surcharge des opérateurs d'égalité

    La surcharge de ces opérateurs dans une classe dote cette dernière d'une relation d'équivalence. Une telle classe est dite Equality Comparable dans la documentation SGI de la bibliothèque standard du C++.

   Le listing ci-dessous illustre la surcharge de l'opérateur == de la classe CPoint, vue précédemment :
 
class CPoint
{
    int m_X;
    int m_Y;

  public :
    // ...
    bool operator == (const CPoint & P) throw ()
    {
        return (m_X == P.X) && (m_Y == P.m_Y);

    } // operator ==

}; // CPoint

Remarque : dans de nombreux cas, la relation d'équivalence peut être définie à partir de l'opérateur < , par exemple, pour une classe CX :
 
bool CX::operator == (const CX & X) { return !((*this < X) | (X < *this)); }

Opérateur d'égalité générique

    Pour doter une classe d'une relation d'équivalence, il n'est pas nécessaire qu'elle possède une surcharge des deux opérateurs d'égalité. Seul l'opérateur == est nécessaire, une définition générique de l'opérateur  est disponible dans la bibliothèque standard, dans le sous-espace de noms rel_ops de l'espace de noms standard std. Son utilisation nécessite l'inclusion du fichier <utility> qui contient la déclaration suivante :
 
namespace std {
    namespace rel_ops {
        template <class T> bool operator != (const T&, const T&);
    }
}

    La définitions correspondante peut être :
 
template <class T>
inline bool std::rel_ops operator != (const T& a, const T& b)
{
    return !(a==b);
}


[1] Ces commodités sont signalées dans la littérature par des phrases comme "It exists only for the sake of convenience" ou "sometimes referred to as “syntactic sugar”"