Professional C__ - Marc Gregoire [211]
map dataMap[1] = Data(4); dataMap[1] = Data(6); auto it = dataMap.find(1); if (it != dataMap.end()) { it->second.setVal(100); } Code snippet from MapBasics\MapFind.cpp As you can see, using find() is a bit clumsier, but it’s sometimes necessary. If your compiler does not support the C++11 auto keyword you need to call find() as follows: map Code snippet from MapBasics\MapFind.cpp If you only want to know whether or not an element with a certain key is in the map, you can use the count() member function. It returns the number of elements in the map with a given key. For maps, the result will always be 0 or 1 because there can be no elements with duplicate keys. The following section shows an example using count(). Removing Elements The map allows you to remove an element at a specific iterator position or to remove all elements in a given iterator range, in amortized constant and logarithmic time, respectively. From the client perspective, these two erase() methods are equivalent to those in the sequential containers. A great feature of the map, however, is that it also provides a version of erase() to remove an element matching a key. Here is an example: map dataMap[1] = Data(4); cout << "There are " << dataMap.count(1) << " elements with key 1" << endl; dataMap.erase(1); cout << "There are " << dataMap.count(1) << " elements with key 1" << endl; Code snippet from MapBasics\MapErase.cpp The output should be as follows: There are 1 elements with key 1 There are 0 elements with key 1 map Example: Bank Account You can implement a simple bank account database using a map. A common pattern is for the key to be one field of a class or struct that is stored in the map. In this case, the key is the account number. Here are simple BankAccount and BankDB classes: class BankAccount { public: BankAccount(int acctNum, const std::string& name) : mAcctNum(acctNum), mClientName(name) {} void setAcctNum(int acctNum) { mAcctNum = acctNum; } int getAcctNum() const { return mAcctNum; } void setClientName(const std::string& name) { mClientName = name; } std::string getClientName() const { return mClientName; } protected: int mAcctNum; std::string mClientName; }; class BankDB { public: BankDB() {} // Adds acct to the bank database. If an account exists already // with that number, the new account is not added. Returns true // if the account is added, false if it's not. bool addAccount(const BankAccount& acct); // Removes the account acctNum from the database. void deleteAccount(int acctNum); // Returns a reference to the account represented // by its number or the client name. // Throws out_of_range if the account is not found. BankAccount& findAccount(int acctNum) throw(std::out_of_range); BankAccount& findAccount(const std::string& name) throw(std::out_of_range); // Adds all the accounts from db to this database. // Deletes all the accounts from db. void mergeDatabase(BankDB& db); protected: std::map }; Code snippet from BankAccount\BankDB.h Here are the implementations of the BankDB methods, with comments explaining the code: bool BankDB::addAccount(const BankAccount& acct) { // Do the actual insert, using the account number as the key auto res = mAccounts.insert(make_pair(acct.getAcctNum(), acct)); // Return the bool field of the pair specifying success or failure return res.second; } void BankDB::deleteAccount(int acctNum) { mAccounts.erase(acctNum); } BankAccount& BankDB::findAccount(int acctNum) throw(out_of_range) { // Finding an element via its key can be done with find() auto it = mAccounts.find(acctNum); if (it == mAccounts.end()) { throw out_of_range("No account with that number."); } // Remember that iterators into maps refer to pairs of key/value return it->second; } BankAccount& BankDB::findAccount(const string& name) throw(out_of_range) { // Finding an element by a non-key attribute