4 Replies - 778 Views - Last Post: 24 October 2011 - 07:36 AM Rate Topic: -----

#1 SnoBunny85  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 87
  • Joined: 02-March 10

No match for 'operator>' error

Posted 21 October 2011 - 11:03 AM

Here is my coding:

/*
 * This file simulates a variation of the producer-consumer paradigm, where the
 * producer is adding change to a change purse, and the consumer is using it to
 * pay bills.  There is one producer and two consumer threads.  All amounts are
 * determined at random.  Bills arrive at random and are kept until paid.  The
 * purse is limited to $10.00, and when it exceeds that amount, the producer
 * goes to sleep.  When it falls below that amount, or when a consumer cannot
 * pay some bill because the purse contains the wrong coins, it wakes the
 * producer.
 */
#include <iostream>
#include <iomanip>
#include <string>
#include <list>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include "simthread.h"

using namespace std;
using namespace simthread;

// Change.
class Change {
public:
        enum denom_t { PENNIES, NICKELS, DIMES, QUARTERS, HALVES, DOLLARS };
        static const int NUM_DENOM = 6;
private:
        // Count of each type of coin, subscripted by the enum.
        int counts[NUM_DENOM];
        static const int vals[NUM_DENOM];

        // Copy in a set of counts.
        void copyin(int countsp[]) {
                for(int n = 0; n < NUM_DENOM; ++n)
                        counts[n] = countsp[n];
        }

public:
        void clear() { for(int n = 0; n < NUM_DENOM; ++n) counts[n] = 0; }

        Change() { clear(); }

        // Just find out how much we've got of a given denom.
        int count(denom_t which) const { return counts[(int)which]; }

        // Add some (but see below).
        void add(int amt, denom_t which) { counts[(int)which] += amt; }
        void add(const Change &add) {
                for(int n = 0; n < NUM_DENOM; ++n)
                        counts[n] += add.counts[n];
        }

        // Get out a certain amount.  If possible, the argument is filled
        // with the coins, this object is reduced by that amount, the argument
        // receives the couns, and the method returns true.
        // If not possible, return false and make no change.
        bool take(int amt, Change &to);

        // Total value.
        int val() {
                int ret = 0;
                for(int n = 0; n < NUM_DENOM; ++n)
                        ret += counts[n]*vals[n];
                return ret;
        }

        // Print the object.
        void pr(ostream &out) const;

        // This allows you to compare change objects for equality and
        // inequality.
        bool operator==(const Change &that) const {
                for(int n = 0; n < NUM_DENOM; ++n)
                        if(counts[n] != that.counts[n]) return false;
                return true;
        }
        bool operator!=(const Change &that) const { return !(*this == that); }
};

// Initializes the constant static field that describe the coin values.
const int Change::vals[Change::NUM_DENOM] = { 1, 5, 10, 25, 50, 100 };

// Take a certain amount.
bool Change::take(int amt, Change &to)
{
        // Partial result.
        int take_counts[NUM_DENOM];
        for(int i = 0; i < NUM_DENOM; ++i) take_counts[i] = 0;

        // For the coins we have, one backtrack could be needed.
        int sub = NUM_DENOM - 1; // Currently assigning highest-value coin.
        for(int i = 2; i--; ) {
                // Scan down the denominations choosing numbers of coins for
                // each of them.
                for(; sub >= 0; --sub) {
                        int use = amt / vals[sub];
                        if(use > counts[sub]) use = counts[sub];
                        take_counts[sub] = use;
                        amt -= use * vals[sub];
                }

                // The only possibly-useful backtrack is when we fail after
                // assigning an odd number of quarters.
                if(amt > 0 && take_counts[(int)QUARTERS] % 2 == 1) {
                        // Remove one quarter and all smaller coins, and
                        // restart with dimes.
                        amt += vals[(int)QUARTERS];
                        take_counts[(int)QUARTERS]--;
                        for(int i = (int)DIMES; i >=0; --i) {
                                amt += vals[i]*take_counts[i];
                                take_counts[i] = 0;
                        }
                        sub = (int)DIMES;
                        continue;
                }

                // If the above test didn't create a backtrack, we're done,
                // succeed or fail.
                break;
        }

        // If this failed to make the given amount, just return false.
        // Otherwise, remove the coins from us and place them in the
        // argument object.
        if(amt > 0) return false;
        for(int i = 0; i < NUM_DENOM; ++i) counts[i] -= take_counts[i];
        to.copyin(take_counts);
        return true;
}

// Printer.
void Change::pr(ostream &out) const
{
        char nlets[] = "pndqh$";
        int tot = 0;
        for(int d = (int)DOLLARS; d >= (int)PENNIES; --d) {
                if(counts[d] > 0) {
                        tot += vals[d] * counts[d];
                        out << counts[d] << nlets[d];
                }
        }
        if(tot == 0) out << "/";
        out << "[";
        if(tot >= 100) out << tot / 100;
        else out << "0";
        out << "." << setw(2) << setfill('0') << tot % 100 << "]"
            << setfill(' ');
}

// Support << for Change objects.
ostream & operator<<(ostream &strm, const Change &c)
{
        c.pr(strm);
        return strm;
}

// Convenient adding.
struct ChangeInc {
        Change::denom_t type;
        int amt;
        ChangeInc(Change::denom_t _type, int _amt): type(_type), amt(_amt) { }
};
Change & operator<<(Change &c, ChangeInc ci) {
        c.add(ci.amt, ci.type);
        return c;
}
inline ChangeInc cents(int amt) { return ChangeInc(Change::PENNIES, amt); }
inline ChangeInc nickels(int amt) { return ChangeInc(Change::NICKELS, amt); }
inline ChangeInc dimes(int amt) { return ChangeInc(Change::DIMES, amt); }
inline ChangeInc quarters(int amt) { return ChangeInc(Change::QUARTERS, amt); }
inline ChangeInc halves(int amt) { return ChangeInc(Change::HALVES, amt); }
inline ChangeInc dollars(int amt) { return ChangeInc(Change::DOLLARS, amt); }

// The change test driver is normally ignored.  Use -DCHANGETEST on the
// compile command line line to create the change test driver.
#ifdef CHANGETEST

// Test the take function.
void taketest(Change &c, int amt)
{
        Change q;
        Change oldc = c;
        if(!c.take(amt, q)) cout << "(take failed) ";
        cout << "take " << amt << " leaves " << c << " " << q << endl;
        q.add(c);
        if(q != oldc) cout << "*** add change failed ***" << endl;
}

main()
{
        Change c;
        cout << c << endl;
        c << halves(3) << dimes(2) << quarters(3) << cents(4);
        cout << "have " << c << endl;

        taketest(c,32);
        taketest(c,63);
        taketest(c,195);
        taketest(c,23);

        c << dimes(3) << nickels(1) << cents(7);
        cout << "\nhave " << c << endl;

        taketest(c,84);
        taketest(c,31);

        c.clear();
        c << dollars(2) << quarters(5) << dimes(3) << nickels(5) << cents(38);
        cout << "\nhave " << c << endl;

        taketest(c, 315);
        taketest(c, 41);
        taketest(c, 23);
        taketest(c, 25);

        c.clear();
        c << dollars(2) << quarters(5) << dimes(4) << cents(6);
        cout << "\nhave " << c << endl;

        taketest(c, 32);
        taketest(c, 24);
        taketest(c, 164);
        taketest(c, 160);
}

#else

/* This is the mutex to protect the change purse, and the purse. */
mutex_t purse_mutex;
Change change_purse;

/* This the event which allows the generator to notify the consumer to
   wake up and spend. */
syncer_t purse_increased(purse_mutex);

/* This the event is used to wait while the purse is full enough. */
syncer_t purse_insufficient(purse_mutex);

/* The purse is sufficient when it contains at least 10.00 and was able
   to pay at least one bill. */
const int ENOUGH = 1000;

/* Requests the threads to stop. */
volatile bool dostop = false;

/* This mutex synronizes printing so the messges aren't jumbled together. */
mutex_t print_mutex;

/* Return a random number in a range.*/
int randrange(int low, int high)
{
        return rand() % (high-low+1) + low;
}

/* Utility for printing integer cents in X.XX form.  Next two classes and one
   function. */
class pdstrm {
        ostream &strm;
public:
        pdstrm(ostream &_strm): strm(_strm) { }
        ostream &operator<<(int i) {
                strm << i / 100 << ".";
                strm << setfill('0') << setw(2) << i % 100
                      << setfill(' ');
                return strm;
        }
        operator ostream &() { return strm; }
};
class PrDols {
} dols;
pdstrm operator<<(ostream &strm, PrDols&d) {
        return pdstrm(strm);
}

/* This is the generator thread.  It repeats until the dostop flag is set,
   randomly receiving a bill and adding it to the purse.  If the purse becomes
   large enough, it goes to sleep until the consumer wakes it. */
void generator()
{
        int bigct = randrange(4,6);

        while(!dostop) {
                /* Add some random change to the pot.  Every so often,
                   it's a big one. */
                Change addme;
                if(bigct == 0) {
                        bigct = randrange(10,20);
                        addme << dollars(randrange(0,1))
                              << halves(randrange(0,2))
                              << quarters(randrange(0,6))
                              << dimes(randrange(0,23))
                              << nickels(randrange(0,5))
                              << cents(randrange(0,15));
                } else {
                        --bigct;
                        addme << quarters(randrange(0,2))
                              << dimes(randrange(0,2))
                              << nickels(randrange(0,3))
                              << cents(randrange(0,5));
                }


                /* Make a quick copy of the purse value for printing. */
                purse_mutex.lock();
                Change newpurse = change_purse;
                purse_mutex.unlock();

                /* Print a message. */
                print_mutex.lock();
                cout << "Adding " << addme << " to " << newpurse << endl;
                print_mutex.unlock();

                /* Add them to the purse and resume any thread that was
                   waiting for the purse contents to increase.  Also make
                   a copy of the new purse for printing w/o holding the
                   purse mutex.  Then, if there's enough, sleep a while. */
                purse_mutex.lock();

                //********if purse is greater than $10
                if(change_purse > 1000)
                {
                    purse_insufficient(change_purse);
                }
                else
                {
                    change_purse.add(addme);
                    purse_increased.notify();

                }
                purse_mutex.unlock();
        }
}

/* This is the consumer thread.  It randomly receives bills of a random amount,
   and tries to pay them.  It retains a list of bills and tries to pay each one
   of them when the purse increases.  It keeps them until paid, but new ones
   arrive each iteration.  Whenever the purse is too small, or if there are
   outstanding bills that can't be paid, it wakes up the generator. */
void consumer()
{
        // List of outstanding bills.
        list<int> bills;

        while(!dostop) {
                /* Create a random bill and add it to the list. */
                int bill = randrange(5,120) + randrange(0,50);
                if(randrange(0,5) == 5) bill += 100;
                bills.push_back(bill);
                print_mutex.lock();
                cout << "Got bill for " << dols << bill << endl;
                print_mutex.unlock();

                // See which bills we can pay, and do so.  Remember if we
                // could pay one.
                list<int>::iterator i = bills.begin();
                while(i != bills.end()) {
                        // Advance the list pointer, but keep a pointer
                        // to the old bill.
                        list<int>::iterator billp = i++;

                        // Try to pay the bill.
                        purse_mutex.lock();
                        Change got;
                        bool paid = change_purse.take(*billp, got);
                        Change new_purse = change_purse;
                        purse_mutex.unlock();

                        // Print the result.
                        print_mutex.lock();
                        if(paid) {
                                cout << "Paid bill for "
                                     << dols << *billp
                                     << " leaving " << new_purse
                                     << endl;
                        } else
                                cout << "Can't pay " << dols << *billp
                                     << " from " << new_purse << endl;
                        print_mutex.unlock();

                        // Get rid of the bill if we paid it.
                        if(paid)
                                bills.erase(billp);
                }

                /* If the purse is small, or couldn't pay off any bills,
                   restart the producer if it's waiting for a need.  Then wait
                   for the purse to increase before we try paying bills
                   anymore. */
               purse_mutex.lock();
                if(paid || change_purse > 1000)
                {
                    if(!dostop)
                        purse_increased.wait_unlocked();
                    change_purse.notify();

                }
                else
                {
                    yield();
                }
                purse_mutex.unlock();
        }
}

int main()
{
        srand(time(0) ^ 0x3982);

        // Create the two threads.
        thread_handle_t prod, firstCon, secondCon;
        prod = thread_call(generator);
        firstCon = thread_call(consumer);
        firstCon.ok();

        //added one more thread
        secondCon = thread_call(consumer);
        secondCon.ok();

        // Let them run for three seconds, then ask them to stop.
        snooze(3000);
        dostop = true;

        // Make sure the threads aren't waiting on notifications.
        purse_increased.notify_under_temp_lock();

        // Wait for them to do so.
        prod.join();
        firstCon.join();
        secondCon.join();

        exit(0);
}
#endif




I keep getting an error in the void generator() method where I put in the coding if(change_purse < 1000).. it says no match for 'operator>' in 'change_purse > 1000'... i am suppose to be writing code that states if the change purse is greater than 10 dollars it should wait, else it should add change and notify the consumer...
My question is: Why am i getting this error??
//********if purse is greater than $10
                if(change_purse > 1000)
                {
                    purse_insufficient(change_purse);
                }
                else
                {
                    change_purse.add(addme);
                    purse_increased.notify();

                }
                purse_mutex.unlock();



Is This A Good Question/Topic? 0
  • +

Replies To: No match for 'operator>' error

#2 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6049
  • View blog
  • Posts: 23,474
  • Joined: 23-August 08

Re: No match for 'operator>' error

Posted 21 October 2011 - 11:13 AM

change_purse is your class. It does not have an operator> (or operator<) method.

Are you sure you don't want to call one of the members of your class instead to give you the data you want?
Was This Post Helpful? 0
  • +
  • -

#3 SnoBunny85  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 87
  • Joined: 02-March 10

Re: No match for 'operator>' error

Posted 23 October 2011 - 08:43 AM

Call one of the members how?? Like what do you mean??
Was This Post Helpful? 0
  • +
  • -

#4 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6049
  • View blog
  • Posts: 23,474
  • Joined: 23-August 08

Re: No match for 'operator>' error

Posted 23 October 2011 - 10:02 AM

Surely, if you wrote the rest of this code, you know how to call a member function!
Was This Post Helpful? 0
  • +
  • -

#5 SnoBunny85  Icon User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 87
  • Joined: 02-March 10

Re: No match for 'operator>' error

Posted 24 October 2011 - 07:36 AM

See, my professor wrote most of the code. Our project was to add code to the generator and producer parts of the program. One of the parts is to compare the change purse to ten dollars and if it is greater than ten dollars do this, else do something else. I know how to do the coding inside of the loop just not sure why I am getting an error with the comparison operator...
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1