Comparable playing cards I have written a working implementation of a Poker card that I want to be comparable. I feel that my solution is somewhat bloated in C++, and want to ask if I should have done something different to make it more concise.

#ifndef POKER_CARD_H
#define POKER_CARD_H

enum Value { Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace};
enum Color {Hearts, Spades, Dimonds, Clubs};

namespace {
    int as_int(Value value){
        switch(value){
            case Value::Two     : return 2;
            case Value::Three   : return 3;
            case Value::Four    : return 4;
            case Value::Five    : return 5;
            case Value::Six     : return 6;
            case Value::Seven   : return 7;
            case Value::Eight   : return 8;
            case Value::Nine    : return 9;
            case Value::Ten     : return 10;
            case Value::Jack    : return 11;
            case Value::Queen   : return 12;
            case Value::King    : return 13;
            case Value::Ace     : return 14;
        }
    }
    int as_int(Color color){
        switch(color){
            case Color::Dimonds : return 1;
            case Color::Clubs   : return 2;
            case Color::Hearts  : return 3;
            case Color::Spades  : return 4;
        }
    }
}

class Card {

public:
    Card(Value value, Color color);

    Color getColor() const;

    Value getValue() const;

private:
    Value value;
    Color color;
};

inline bool operator==(const Card&amp; lhs, const Card&amp; rhs) {
    return ((rhs.getValue() == lhs.getValue()) &amp;&amp; (rhs.getColor() == lhs.getColor()));
}
inline bool operator!=(const Card&amp; lhs, const Card&amp; rhs) {return !operator==(lhs,rhs);}
inline bool operator&lt; (const Card&amp; lhs, const Card&amp; rhs) {
    if (as_int(lhs.getValue()) &lt; as_int(rhs.getValue())){
        return true;
    }
    else if (as_int(rhs.getValue()) == as_int(lhs.getValue())){
        return as_int(lhs.getColor()) &lt; as_int(rhs.getColor()) ? true : false;
    }
    else {
        return false;
    }
}
inline bool operator&gt; (const Card&amp; lhs, const Card&amp; rhs) {return  operator&lt; (rhs,lhs);}
inline bool operator&lt;=(const Card&amp; lhs, const Card&amp; rhs) {return !operator&gt; (lhs,rhs);}
inline bool operator&gt;=(const Card&amp; lhs, const Card&amp; rhs) {return !operator&lt; (lhs,rhs);}


#endif //POKER_CARD_H
Plain enum (unlike enum class) convert implicitly to integers, so there's no need for the as_int() functions if you declare the enums in ascending order.  You probably want the suits in the order ♣♦♥♠ if you want to re-use your cards for Bridge as well as Poker.

I had to make up the constructor and get methods, since they are missing from the review:

Card(Value value, Color color)
    : value{value},
      color{color}
{}

Color getColor() const { return color; };

Value getValue() const { return value; };


I also created a simple test program that returns non-zero if we break the expectations:

int main()
{
    return
        + (Card{Two, Clubs} &gt; Card{Ace, Spades})
        + (Card{Two, Clubs} &gt; Card{Two, Spades})
        + (Card{Two, Spades} &gt; Card{Ace, Spades});
}


Now, we can remove the as_int():

enum Value { Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace};
enum Color { Clubs, Dimonds, Hearts, Spades};




inline bool operator==(const Card&amp; lhs, const Card&amp; rhs)
{
    return rhs.getValue() == lhs.getValue()
        &amp;&amp; rhs.getColor() == lhs.getColor();
}

inline bool operator!=(const Card&amp; lhs, const Card&amp; rhs) { return !(lhs==rhs); }

inline bool operator&lt; (const Card&amp; lhs, const Card&amp; rhs)
{
    if (lhs.getValue() &lt; rhs.getValue()) {
        return true;
    }
    else if (rhs.getValue() == lhs.getValue()) {
        return lhs.getColor() &lt; rhs.getColor() ? true : false;
    }
    else {
        return false;
    }
}

inline bool operator&gt; (const Card&amp; lhs, const Card&amp; rhs) {return rhs &lt; lhs;}
inline bool operator&lt;=(const Card&amp; lhs, const Card&amp; rhs) {return !(lhs&gt;rhs);}
inline bool operator&gt;=(const Card&amp; lhs, const Card&amp; rhs) {return !(lhs&lt;rhs);}


Note that this ternary conditional:

        return lhs.getColor() &lt; rhs.getColor() ? true : false;


is exactly equivalent to this:

        return lhs.getColor() &lt; rhs.getColor();


But we can simplify the &lt; much further by delegating to std::tuple:

inline bool operator&lt; (const Card&amp; lhs, const Card&amp; rhs) {
    return std::tuple(lhs.getValue(), lhs.getColor()) &lt; std::tuple(rhs.getValue(), rhs.getColor());
}


In C++20, the entire set of 6 comparisons can be replaced with a single function:

public:
    auto operator&lt;=&gt;(const Card&amp;) const = default;