// pair class definition template class pair { T m_left; U m_right; public: pair(); pair(const T& t, const U& u); const T& left() const; T& left(); const U& right() const; U& right(); pair& operator+=(const pair& other); }; template pair operator+(const pair& a, const pair& b); // traits class to indicate whether we should use + instead of += to add m_left and m_right struct use_plusequals {}; struct use_plus {}; template struct my_operator_traits { typedef use_plusequals addition; }; // pair class implementation template pair::pair() { } template pair::pair(const T& t, const U& u) : m_left(t), m_right(u) { } template const T& pair::left() const { return m_left; } template T& pair::left() { return m_left; } template const U& pair::right() const { return m_right; } template U& pair::right() { return m_right; } // helper functions for delegating addition of left or right template void pair_add_left(pair& p, const pair& q, use_plusequals); template void pair_add_left(pair& p, const pair& q, use_plus); template void pair_add_right(pair& p, const pair& q, use_plusequals); template void pair_add_right(pair& p, const pair& q, use_plus); template pair& pair::operator+=(const pair& other) { // to write the pair class simply, just use the following two statements // m_left += other.m_left; // m_right += other.m_right; // the following two lines dispatch to the appropriate function depending on whether we want it to use + or += pair_add_left(*this, other, typename my_operator_traits::addition()); pair_add_right(*this, other, typename my_operator_traits::addition()); return *this; } template pair operator+(const pair& a, const pair& b) { pair dup(a); dup += b; return dup; } template void pair_add_left(pair& p, const pair& q, use_plusequals) { p.left() += q.left(); } template void pair_add_left(pair& p, const pair& q, use_plus) { p.left() = p.left() + q.left(); } template void pair_add_right(pair& p, const pair& q, use_plusequals) { p.right() += q.right(); } template void pair_add_right(pair& p, const pair& q, use_plus) { p.right() = p.right() + q.right(); }