对abs的暧昧呼唤

Ent*_*ops 10 c++ macos cmath c++11

我有一个自定义数据类型,实际上可以是floatdouble.在除OSX之外的每个操作系统上,我都能够成功构建此C++ 11模板:

#include <cmath>
#include <cstdlib>
#include <cstdint>

template< class REAL_T >
inline REAL_T inhouse_abs(REAL_T i_val)
{
    return std::abs((REAL_T)i_val);
}

int main()
{
    int32_t ui = 2;
    inhouse_abs(ui);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,clang 6.0(3.5 LLVM)报告了一个模糊的函数调用.如果我abs改为fabs,则在OSX上解决了错误,但现在我的Linux clang,gcc和Visual Studio上出现了相同的错误.

使用fabs的Visual Studio出错:

349 error C2668: 'fabs' : ambiguous call to overloaded function
Run Code Online (Sandbox Code Playgroud)

UPDATE

这个例子在我们的OS X系统上编译,尽管在几乎相同的项目中它没有.解决方案<cstdlib>明确包含在源代码中,而不是包含在另一个头文件中.原因尚不清楚,但似乎是xcode/clang没有跟随我们的标题包括正确.

Sha*_*our 10

问题是,cmath中的std :: abslibc++的完整重载并不完全符合C++ 11 :

double      fabs( Integral arg ); (7)   (since C++11)
Run Code Online (Sandbox Code Playgroud)

包含cstdlib可以解决您的问题,因为该标头具有专门针对整数类型的重载.

作为参考,草案C++ 11标准部分26.8 [c.math]段落11说:

此外,还应有足够的额外过载来确保:

并包括以下项目:

  1. 否则,如果对应于double参数的任何参数具有double类型或整数类型,则对应于double参数的所有参数都将有效地转换为double.

由于LWG活动问题2192,这种情况很可能会发生变化:std :: abs(0u)的有效性和返回类型不清楚.由于此缺陷报告libc++cmath出现的问题,我猜测选择不提供重载.

看到std :: abs(0u)是不正确的?有关这方面的更多细节.