Let\'s take the following example program:
#include
namespace half_float
{
template struct half_expr {};
struct hal
I think I found the cause. The C++ standard says in section 26.8 [c.math], that for the mathematical functions of the C library,
there shall be additional overloads sufficient to ensure:
- If any argument corresponding to a double parameter has type long double, then all arguments corresponding to double parameters are effectively cast to long double.
- Otherwise, if any argument corresponding to a double parameter has type double or an integer type, then all arguments corresponding to double parameters are effectively cast to double.
- Otherwise, all arguments corresponding to double parameters are effectively cast to float.
Which can also be seen in the atan2 documentation.
Those overloads are provided by VS 2012 through the use of a general function template of the form:
template common_float_type::type atan2(T, U);
So we have a template function whose instantiation would involve an implicit conversion (from half& to const half_expr) and a template function which can be instantiated directly. Thus the latter is preferred. This doesn't happen for the 1-argument functions because for those there only has to be a general version for integral arguments, which is provided by VS 2012 for only those using a std::enable_if of std::is_integral.
But I think the standard is a bit unclear about the fact that those "additional overloads" are to be provided only for builtin types. So in the end I'm still not sure if VS 2012 strictly violates the standard with its overly generic functions or if it is a viable implementation option to provide those.
EDIT: As it seems, there is already defect report 2086 for the standard's unclear wording and a fix is on it's way, limiting the requirement for those additional overloads to only arithmetic types. Since this seems to have always been the original intent (and realized by nearly all existing implementations) and it was merely the wording that was unclear, I would indeed regard this a bug in VS 2012's implementation.