
@ Experienced Boosters: I fear lots of code here! Can Matthieu write global ops for binary arithmetic with PODs in a clever way combining boost::enable_if with is_integral, etc.? Or does the developer really need to diligently write all those global ops (with PODs on both RHS and LHS) for unequivocal resolution with char, signed char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, long long, unsigned long long, float, double, long double, and maybe even const char*.
For sure, off the top of my head and untested with a real compiler, but how about:
template <class Float, class Arithmetic> typename enable_if<is_arithmetic<Arithmetic>, complex<typename boost::math::tools::promote_args<Float, Arithmetic>::type> >::type operator *(const complex<Float>& a, const Arithmetic& val) { typedef complex<typename boost::math::tools::promote_args<Float, Arithmetic>::type> result_type; return result_type(a.real() * val, a.imag() * val); }
So basically this is only selected as a possible overload if the second argument is a builtin arithmetic type, then the type of the result is calculated using a helper template from Boost.Math which effectively promotes integers to double and then computes typeof(Float*promoted(Arithmetic)). Basically promote_args implements the logic in 26.8 para 11 of C++11.
So that:
complex<float> * double -> complex<double> complex<float> * int -> complex<double> (because integers get promoted to double) complex<double> * long long -> complex<double>
etc etc.
HTH, John.
PS of course we could argue that ints longer than 53 bits should be promoted to long double to try to avoid loss of digits.... but that's a whole other ball game....
But then aren't you removing the optimization complex<double> * int that Chris originally proposed ? As your int is promoted to a double. Or are you talking about non-POD integer-like types ? Bests, Matthieu -- Matthieu Schaller