#include <iostream>

template<typename T>
class Vector2
{
public:
  Vector2(T x, T y)
  : x(x), y(y)
  {}

  template<typename U>
  Vector2<U> cast() const { return Vector2<U>((U)x, (U)y); }

  T x;
  T y;
};

template<typename T>
class Line2
{
public:
  Line2(Vector2<T> a, Vector2<T> b)
  : a(a), b(b)
  {}

  double gradient() const
  {
    Vector2<double> ad(a.cast<double>());
    Vector2<double> bd(b.cast<double>());

    return (bd.y - ad.y) / (bd.x - ad.x);
  }

  Vector2<T> a;
  Vector2<T> b;
};

int main()
{
  Vector2<int> intVector(10,5);
  Vector2<double> doubleVector(intVector.cast<double>());

  Line2<int> intLine(Vector2<int>(0,0), Vector2<int>(1,3));
  Line2<double> doubleLine(Vector2<double>(0,0), Vector2<double>(0.5,1.23));

  std::cout << "Line2<int>.gradient = " << intLine.gradient() << std::endl;
  std::cout << "Line2<double>.gradient = " << doubleLine.gradient() << std::endl;
}
