Incorrect overload resolution for 2-argument functions

前端 未结 3 410
粉色の甜心
粉色の甜心 2021-01-12 02:30

Let\'s take the following example program:

#include 

namespace half_float
{
    template struct half_expr {};

    struct hal         


        
3条回答
  •  旧巷少年郎
    2021-01-12 03:12

    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:

    1. 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.
    2. 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.
    3. 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.

提交回复
热议问题