#include <iostream>
#include <functional>

struct Coordinate
{
    double x;
    double y;
    Coordinate(double x, double y) : x(x), y(y) {}
};

Coordinate operator*(double d, Coordinate c)
{ return {c.x*d, c.y*d}; }

Coordinate operator*(Coordinate c, double d)
{ return d*c; }

Coordinate operator+(Coordinate lhs, Coordinate rhs)
{ return {lhs.x +rhs.x, lhs.y + rhs.y}; }

std::ostream& operator<<(std::ostream& out, const Coordinate& c)
{ return out << '(' << c.x << ", " << c.y << ')'; }

class Line
{
public:
    Line(const Coordinate& start, const Coordinate& end)
        : mP1(start), mP2(end)
    {}

    std::function<Coordinate(double)> get_path() const
    {
        return [this](double t) {
            return (1-t)*this->mP1 + t*this->mP2;
        };
    }
private:
    Coordinate mP1;
    Coordinate mP2;
};

struct Movable {
    std::function<Coordinate(double)>  mpPath;

    template<typename T>
    void setPath(const T& obj)
    {
        mpPath = obj.get_path();
    }

    Coordinate position(double d)
    {
        return mpPath(d);
    }
};

int main()
{
    Line my_line(Coordinate(0.0, 0.0),
                 Coordinate(10.0, 10.0));
    Movable object2;
    object2.setPath(my_line);
    std::cout << object2.position(0.5); // prints (5, 5)
}