//professional c++ 4th edition p413
#include <iostream>
#include <list>
#include <deque>
#include <algorithm>
#include <functional>
#include <string>
#include <unordered_set>
template <typename T>
inline void PRINT_ELEMENTS (const T& coll,
const std::string& optstr="")
{
std::cout << optstr;
for (const auto& elem : coll) {
std::cout << elem << ' ';
}
std::cout << std::endl;
}
class Person {
private:
std::string name;
public:
Person (const std::string& n) : name(n) {
}
void print () const {
std::cout << name << std::endl;
}
void print2 (const std::string& prefix) const {
std::cout << prefix << name << std::endl;
}
//...
};
class Customer {
private:
std::string fname;
std::string lname;
long no;
public:
Customer (const std::string& fn, const std::string& ln, long n)
: fname(fn), lname(ln), no(n) {
}
std::string firstname() const {
return fname;
};
std::string lastname() const {
return lname;
};
long number() const {
return no;
};
friend std::ostream& operator << (std::ostream& strm, const Customer& c) {
return strm << "[" << c.fname << "," << c.lname << "," << c.no << "]";
}
};
template <typename T>
inline void hash_combine (std::size_t& seed, const T& val)
{
seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
// auxiliary generic functions to create a hash value using a seed
template <typename T>
inline void hash_val (std::size_t& seed, const T& val)
{
hash_combine(seed,val);
}
template <t