vendredi 22 septembre 2017

MSVC's stdlib and fma() function template

I am writing a mathematical library which provides an FMA (fused multiply-add) primitive for one of my user-defined types (called real). The prototype of the function looks something like:

template <typename T, typename U, typename V, Enabler<T,U,V> = 0>
real fma(T &&x, U &&y, V &&z);

The Enabler<T,U,V> bit is a SFINAE construction that removes the fma() function from the overload set if T, U and V are not all of type real (after the removal of cv qualifications). I am using templates and forwarding references in order to provide the possibility to pilfer resources from one of the function arguments when constructing the return value of the function.

My fma() function is intended to be used via argument-dependent lookup, and it works fine in GCC and clang (both using libstdc++ and libc++). MSVC however errors out:

http://ift.tt/2jOSGus

The problem seems to be the presence of a function template fma() defined in the root namespace:

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xtgmath.h(146): note: or       'float fma<mppp::real,mppp::real,mppp::real>(_Ty1,_Ty2,_Ty3)'
      with
      [
          _Ty1=mppp::real,
          _Ty2=mppp::real,
          _Ty3=mppp::real
      ]
C:\projects\mppp\test\real_basic.cpp(48): note: while trying to match the argument list '(mppp::real, mppp::real, mppp::real)'

As far as I have understood, C specifies the presence of various floating-point overloads for the fma() function, and C++ has more overloads available as std::fma(). According to this page,

http://ift.tt/2xWmBqv

C++ might also provide a function template overload when the arguments are of arithmetic types. MSVC however does not constrain its fma() template to arithmetic types, rather it gobbles up any argument type.

My question is then: is this a valid behaviour from MSVC?

Aucun commentaire:

Enregistrer un commentaire