// smart version of pi namespace boost { namespace math{ // First constant traits for the Constant to figure // the correct type to apply to itself in operation with T // eg (pi --> 'argument_type') * t --> 'result_type' template struct pi_times{ typedef T argument_type; typedef T result_type; }; template struct pi_plus{ typedef T argument_type; typedef T result_type; }; template struct pi_pow{ typedef T argument_type; typedef T result_type; }; // etc // Obviously the traits can be specialised eg ... for int maybe want promotion to double template <> struct pi_times{ typedef double argument_type; typedef double result_type; }; template <> struct pi_plus{ typedef double argument_type; typedef double result_type; }; template <> struct pi_pow{ typedef double argument_type; typedef double result_type; }; // The actual constant struct pi{ template struct apply{ static T const & value; }; template operator T()const {return apply::value;} } ; template T const& pi::apply::value = T(3.1414); // forwarding operators template inline typename pi_times::result_type operator *( T const & t , pi const & p) { return t * typename pi_times::argument_type(p) ; } template inline typename pi_times::result_type operator *( pi const & p, T const & t ) { return typename pi_times::argument_type(p) * t; } template inline typename pi_plus::result_type operator +( T const & t , pi const & p) { return t + typename pi_plus::argument_type(p) ; } template inline typename pi_plus::result_type operator +( pi const & p, T const & t ) { return typename pi_plus::argument_type(p) + t; } template<> struct pi::apply { }; // disallow int conversion }}//boost::math ////////////////////////////////////// #include #include int main() { boost::math::pi pi; float f1 = pi; // float f2 = 2 * pi; // conversion warning due to int constant_times traits float f2a = 2 * float(pi); // float f3 = pi * 2; // conversion warning... etc float f3a = float(pi) * 2; float f4 = 2.f * pi; float f5 = pi * 2.f; double d1 = pi; double d2 = 2 * pi; double d3 = pi * 2; double d4 = 2. * pi; double d5 = pi * 2.; double d6 = pow(double(pi),2); // conversion required for overload }