
Another comment to add to Chris's, you have code like this: template<typename T> inline complex<T> polar(const T& r, const T& theta) { return complex<T>(r*cos(theta), r*sin(theta)); } Which will either: * Not compile if the compiler strictly adhers to the std and doesn't inject cos and sin into the global namespace, or: * Silently do the wrong thing when T is a long double - truncate r and theta to double and call ::cos(double) etc. You can't just add a std:: prefix to all the calls either, as then it won't work with user-defined types whose functions aren't in namespace std. So instead you need: template<typename T> inline complex<T> polar(const T& r, const T& theta) { using std::cos; using std::sin; return complex<T>(r*cos(theta), r*sin(theta)); } In Boost.Math we found this trap so easy to slip into that: * We have a macro "BOOST_MATH_STD_USING" which adds all the possible using declarations to the start of a function. * A concept-checking type std_real_concept, which when passed to a function like the above, won't compile unless it's done right. HTH, John.