
2. If you templatize, then I would like to know the kind of concepts accepted by each ease function. This kind of library is very useful when you can use the same code to interpolate, for example, 2D and 3D vectors, instead of just a value. So it is important to says clearly which operations have to be implemented for the value type to work with the ease.
In the case where the tweener classes are templatized, I think that the main requirement for the type is to support substraction and multiplication.
The easing functions are agnostic with regard to the domain of the interpolated values. They just take the fraction of the interpolation duration represented in [0, 1] and tell "where" the tweened value is in a fraction of the distance between the origin and target values.
So I think that the templatization would need two types: the user type T used in tweener classes and an other type E used in the easing functions. E should be a type that can represent values in [0, 1] and T must accept a multiplication by E.
To me it sounds like your T is a vector in an abstract vector space and your E is the associated scalar type. You just happen to have 1-dimensional vectors called "doubles" right now.
For the case of more complex types like 2D and 3D vectors, I think they could be used for T but, as a user, that is not the way I would use the library. Instead, I guess that I would write a helper function that builds a tweener_group containing a single_tweener on each dimension of the vector.
I could see wanting to perform operations against the abstract vectors directly. This would permit using SSE-like instructions on long vectors (through some suitable abstraction, of course). - Rhys