#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)
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCnN0cnVjdCBDb29yZGluYXRlCnsKICAgIGRvdWJsZSB4OwogICAgZG91YmxlIHk7CiAgICBDb29yZGluYXRlKGRvdWJsZSB4LCBkb3VibGUgeSkgOiB4KHgpLCB5KHkpIHt9Cn07CgpDb29yZGluYXRlIG9wZXJhdG9yKihkb3VibGUgZCwgQ29vcmRpbmF0ZSBjKQp7IHJldHVybiB7Yy54KmQsIGMueSpkfTsgfQoKQ29vcmRpbmF0ZSBvcGVyYXRvciooQ29vcmRpbmF0ZSBjLCBkb3VibGUgZCkKeyByZXR1cm4gZCpjOyB9CgpDb29yZGluYXRlIG9wZXJhdG9yKyhDb29yZGluYXRlIGxocywgQ29vcmRpbmF0ZSByaHMpCnsgcmV0dXJuIHtsaHMueCArcmhzLngsIGxocy55ICsgcmhzLnl9OyB9CgpzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yPDwoc3RkOjpvc3RyZWFtJiBvdXQsIGNvbnN0IENvb3JkaW5hdGUmIGMpCnsgcmV0dXJuIG91dCA8PCAnKCcgPDwgYy54IDw8ICIsICIgPDwgYy55IDw8ICcpJzsgfQoKY2xhc3MgTGluZQp7CnB1YmxpYzoKICAgIExpbmUoY29uc3QgQ29vcmRpbmF0ZSYgc3RhcnQsIGNvbnN0IENvb3JkaW5hdGUmIGVuZCkKICAgICAgICA6IG1QMShzdGFydCksIG1QMihlbmQpCiAgICB7fQoKICAgIHN0ZDo6ZnVuY3Rpb248Q29vcmRpbmF0ZShkb3VibGUpPiBnZXRfcGF0aCgpIGNvbnN0CiAgICB7CiAgICAgICAgcmV0dXJuIFt0aGlzXShkb3VibGUgdCkgewogICAgICAgICAgICByZXR1cm4gKDEtdCkqdGhpcy0+bVAxICsgdCp0aGlzLT5tUDI7CiAgICAgICAgfTsKICAgIH0KcHJpdmF0ZToKICAgIENvb3JkaW5hdGUgbVAxOwogICAgQ29vcmRpbmF0ZSBtUDI7Cn07CgpzdHJ1Y3QgTW92YWJsZSB7CiAgICBzdGQ6OmZ1bmN0aW9uPENvb3JkaW5hdGUoZG91YmxlKT4gIG1wUGF0aDsKCiAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUPgogICAgdm9pZCBzZXRQYXRoKGNvbnN0IFQmIG9iaikKICAgIHsKICAgICAgICBtcFBhdGggPSBvYmouZ2V0X3BhdGgoKTsKICAgIH0KCiAgICBDb29yZGluYXRlIHBvc2l0aW9uKGRvdWJsZSBkKQogICAgewogICAgICAgIHJldHVybiBtcFBhdGgoZCk7CiAgICB9Cn07CgppbnQgbWFpbigpCnsKICAgIExpbmUgbXlfbGluZShDb29yZGluYXRlKDAuMCwgMC4wKSwKICAgICAgICAgICAgICAgICBDb29yZGluYXRlKDEwLjAsIDEwLjApKTsKICAgIE1vdmFibGUgb2JqZWN0MjsKICAgIG9iamVjdDIuc2V0UGF0aChteV9saW5lKTsKICAgIHN0ZDo6Y291dCA8PCBvYmplY3QyLnBvc2l0aW9uKDAuNSk7IC8vIHByaW50cyAoNSwgNSkKfQ==