我正在编写一个数学库,为我的一个用户定义类型(称为real
)提供FMA(融合乘法 - 加法)原语。该函数的原型看起来像:
template <typename T, typename U, typename V, Enabler<T,U,V> = 0>
real fma(T &&x, U &&y, V &&z);
Enabler<T,U,V>
位是SFINAE结构,如果fma()
,T
和U
不是全部类型,则会从重载集中删除V
函数real
(在取消cv资格和参考资格后)。我正在使用模板和转发引用,以便在构造函数的返回值时从其中一个函数参数中窃取资源。
我的fma()
函数旨在通过参数依赖查找来使用,它在GCC和clang(使用libstdc ++和libc ++)中都能正常工作。然而,MSVC出错:
https://ci.appveyor.com/project/bluescarni/mppp/build/557/job/m25u5g59tp49jfl3#L1049
问题似乎是根命名空间中定义的函数模板fma()
的存在:
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)'
据我所知,C指定fma()
函数存在各种浮点重载,而C ++有更多重载可用std::fma()
。根据这个页面,
http://en.cppreference.com/w/cpp/numeric/math/fma
当参数是算术类型时,C ++也可能提供函数模板重载。但是,MSVC不会将其fma()
模板约束为算术类型,而是会吞噬任何参数类型。
我的问题是:这是来自MSVC的有效行为吗?
编辑:我在这里添加了一个最小的例子:
<德尔> http://rextester.com/IAG22173 德尔>