#ifndef SEC6_TRIPLE_SOLN_H_
#define SEC6_TRIPLE_SOLN_H_
// XXX error: previous definition of ‘class Triple<T1, T2, T3>’
//   (Because BuggyMain includes both Triple and Point3D AND the fact
//    that Point3D ALSO includes Triple, we can easily get duplicate
//    definition errors if we don't properly guard our headers)

#include <iostream>

// A class representing a generic 3-tuple.
template <class T1,class T2,class T3>
class Triple {
 public:
  // XXX error: no known conversion for argument 2 from 'const char [8]' to 'std::basic_string<char>&'
  //   (String literals are actually typed as strictly sized const char arrays)
  Triple(const T1 &x, const T2 &y, const T3 &z)
    : x_(x), y_(y), z_(z) { }
  // XXX warning: y_ will be initialized after x_
  //   (Regardless of the initialization list ordering, members will be
  //    initialized in the order they are declared)

  // Simple member accessors.
  T1 get_x() const { return x_; }
  T2 get_y() const { return y_; }
  T3 get_z() const { return z_; }
  void set_x(const T1 &x) { x_ = x; }
  void set_y(const T2 &y) { y_ = y; }
  void set_z(const T3 &z) { z_ = z; }

 private:
  T1 x_;
  T2 y_;
  T3 z_;
}; // XXX error: expected ‘;’ after class definition

// Pass the tuple in the standard format "(x,y,z)" to the out ostream.
template <class T1, class T2, class T3>
std::ostream &operator<<(std::ostream &out, const Triple<T1,T2,T3> &rhs) {
  // XXX error: passing 'const ...' as 'this' argument of ... discards qualifiers
  //   (Since we declared rhs to be const, we can only call const member
  //    functions on it.  The member accessors were incorrectly declared
  //    non-const.)

  out << "(" << rhs.get_x() << "," << rhs.get_y() << "," << rhs.get_z() << ")";
  return out;
}

#endif // SEC6_TRIPLE_SOLN_H_