#include #include class Project { public: using seconds = std::chrono::duration; }; class Timer { public: Timer(float seconds) : _remaining{ seconds } {} virtual bool operator()(Project::seconds, Project::seconds); float remaining() const { return _remaining; } protected: virtual void operator()(Project::seconds time) = 0; private: float _remaining; }; bool Timer::operator()(Project::seconds frame, Project::seconds total) { _remaining -= frame.count(); if (_remaining <= 0) { (*this)(total); return false; } return true; } class Easing : public Timer { public: Easing(float seconds) : Timer{ seconds }, _duration{ seconds } {} bool operator()(Project::seconds, Project::seconds) override; protected: void operator()(Project::seconds) override {} virtual void operator()(float progress, float fraction) = 0; private: float _duration; }; bool Easing::operator()(Project::seconds frame, Project::seconds total) { float elapsed = _duration - remaining(); operator()(frame.count() / _duration, elapsed / _duration); return Timer::operator()(frame, total); } class Slide : public Easing { public: Slide(float duration, long& target, float destination) : Easing{duration}, _target { target }, _destination{ destination }, _start{ target / 0.5 } {} // using Easing::operator(); // required fix protected: void operator()(float progress, float fraction) override; private: long& _target; double _destination, _start; }; void Slide::operator()(float progress, float fraction) { _target += (_destination - _start) * progress); } long x = 16; std::function motion { Slide { 4.0f, x, 12.15f } }; // fails without using declaration