
On Wed, Dec 2, 2009 at 12:46 PM, joel falcou <joel.falcou@lri.fr> wrote:
Michael Fawcett wrote:
template <typename X, typename Y> BOOST_TYPEOF_TPL(X() * X() + Y() * Y()) magnitude_squared(const vector2<X, Y> &v) { return v.x * v.x + v.y * v.y; }
Typeof works, but I'm wondering if it's overkill and that perhaps common_type is much more lightweight and appropriate. promote_args doesn't do quite what I need here, but thank you for pointing that facility out to me.
Regardless, the original post was about how to proceed, and I definitely see reason to break those components out of Boost.Chrono. I didn't mean to hijack the thread ;)
Why not having a proper polymorphic function object that performs the computation and hide the potential uglyness of the type computation ?
struct magnitude_squared_ { template<class Sig> struct result; template<class This,class X, class Y> struct result<This(vector2<X,Y>)> { typedef BOOST_TYPEOF_TPL(X() * X() + Y() * Y()) type; };
template<class X,class Y> typename result<magnitude_squared_(vector2<X,Y>)>::type operator()( vector2<X,Y> const& v ) { return v.x*v.x + v.y*v.y; } };
magnitude_squared_ const magnitude_square = {};
or
template<class X,class Y> typename boost::result_of<magnitude_squared_(vector2<X,Y>)>::type magnitude_squared( vector2<X,Y> const& v ) { magnitude_squared_ callee; return callee(v); }
Bonus is that you can ask the return type of an arbitrary magnitude_squared call in other template function if neede using boost::result_of.
I'll look into this. It certainly sounds attractive! I went down a similar path once, but I didn't like how I had to do this for every free function - dot_product, cross_product, magnitude, normalize, etc. Maybe it's just a one time cost that pays off in the end with usability. Thanks, --Michael Fawcett