Question

I'm working on an assignment where we have to program multiple decks of cards that can interact with each other using vectors (e.g. removing one card from the main deck and adding it to another). The assignment states we must use an overloaded "smaller than" operator from our card struct to determine the correct order of cards by combining it with the std::lower_bound function. So far this is what I have:

void CardDeck::Add(const Card& card)
{
    m_Cards.insert(std::lower_bound(m_Cards.begin(),m_Cards.end(),card,*insert smaller than operator here*),card);
}

And the overloaded "smaller than" operator of the Card struct is as follows. It compares the rank and the suit of the cards based on a predetermined order in an enumeration:

friend bool operator< (const Card& lhs, const Card& rhs)
{
    if(lhs.m_Suit < rhs.m_Suit || (lhs.m_Suit == rhs.m_Suit && lhs.m_Rank < rhs.m_Rank))
    {
        return true;
    }
}

Any help is greatly appreciated. The assignment states we MUST use the overloaded operator. We're not allowed to make a simple "IsSmallerThan()" method of our own.

Many thanks.

EDIT: forgot to mark the problem. Extra info in comments.

Was it helpful?

Solution

By default, std::lower_bound uses the less-than operator for the type behind the iterators. By defining your own operator <, lower_bound should just do the right thing. i.e. calling it like this

std::lower_bound(m_cards.begin(), m_cards.end(), card);

should work fine, give an appropriate operator < defined on card types.

One thing to point out is your code for operator < can be simplified to

friend bool operator< (const Card& lhs, const Card& rhs)
{
   return lhs.m_Suit < rhs.m_Suit || 
       (lhs.m_Suit == rhs.m_Suit && lhs.m_Rank < rhs.m_Rank);
}

(which also fixes a subtle bug in your code).

OTHER TIPS

You need

void CardDeck::Add(const Card& card)
{
    m_Cards.insert(std::lower_bound(m_Cards.begin(),m_Cards.end(),card,std::less<Card>()),card);
}

if you want to really provide a comparator. Since the default is already to use the above, you can also simply leave it out:

void CardDeck::Add(const Card& card)
{
    m_Cards.insert(std::lower_bound(m_Cards.begin(),m_Cards.end(),card),card);
}

You can also simplify your operator< (and make it less error-prone) by using std::tie:

friend bool operator< (const Card& lhs, const Card& rhs)
{
    return std::tie(lhs.m_Suit, lhs.m_Rank) < std::tie(rhs.m_Suit, rhs.m_Rank);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top