不明确的过载调用abs(double)

我有以下C ++代码:

#include <math.h> #include <cmath.h> // per http://www.cplusplus.com/reference/clibrary/cmath/abs/ // snip ... if ( (loan_balance < 0) && (abs(loan_balance) > loan_payment) ) { ... } 

并打击:

 error: call of overloaded 'abs(double)' is ambiguous 

也感兴趣:

 /usr/include/stdlib.h:785: note: candidates are: int abs(int) 

我怎样才能指定编译器需要调用cmath.h中的可以处理浮点数的abs()?

编译器信息(不知道这是否重要):

 [some_man@some_box ~/some_code]# gcc -v Using built-in specs. Target: i386-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr /share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux Thread model: posix gcc version 4.1.2 20080704 (Red Hat 4.1.2-44) 

<math.h>是一个C标准库头。 它在全局命名空间中定义了很多东西。 头<cmath>是该头的C ++版本。 它在命名空间std定义了基本相同的东西。 (有一些区别,就像C ++版本带有一些函数的重载,但这并不重要。)头文件<cmath.h>不存在。

由于供应商不想维护本质上相同的头的两个版本,他们提出了不同的可能性,只有其中一个在幕后。 通常,这就是C头文件(因为C ++编译器能够parsing这个头文件,而相反的头文件却不行),而C ++头文件只包含了这个头文件,并且将所有东西都放到名称空间std 。 或者有一些macrosparsing相同的标题,无论是否包含namespace std 。 为此,在一些环境中,如果头文件没有文件扩展名(比如编辑器不能突出显示代码等),那就很尴尬。 所以有些供应商可能是一个<cmath>包括其他扩展名为.h头文件。 或者一些映射所有包含匹配<cblah><blah.h> (通过macros魔法,当__cplusplus被定义时变成C ++头,否则变成C头)或者<cblah.h>

这就是为什么在一些平台上,包括像<cmath.h>这样不应该存在的东西,最初会成功的,尽pipe它可能会使编译器在以后出现失败。

我不知道你使用哪个标准库实现。 我想这是GCC的一个,但是我不知道,所以我不能解释你的情况究竟发生了什么。 但它肯定是上述厂商特定的黑客之一的混合,你包括你不应该包括自己的头。 也许这是<cmath>映射到<cmath.h>与你没有定义的特定(一组)macros的一个,所以你最终得到了两个定义。

但是,请注意,这段代码仍然不应该编译:

 #include <cmath> double f(double d) { return abs(d); } 

全局命名空间中不应该有abs() (它是std::abs() )。 但是,按照上述实施技巧,可能会有。 稍后移植这样的代码(或只是试图与你的供应商的下一个版本不允许这样做)进行编译可能是非常乏味的,所以你应该留意这一点。

它归结为: math.h是从C ,并创build了10多年前。 在math.h中,由于其原始性质, abs()函数对于整数types是“本质上”的,如果想获得double的绝对值,则必须使用fabs() 。 当C ++被创build时,它花费了math.h并取得了成功。 cmath实质上是math.h,但对于C ++来说却有所改进。 它改进了一些东西,比如必须区分fabs()和abs,并且为double和integertypes创build了abs() 。 总结一下:使用math.h,使用abs()作为整数, fabs()作为双精度,或者使用cmath,只需要abs就可以了(简单和推荐)

希望这有助于任何有同样问题的人!

使用fabs()而不是abs(),这是相同的,但对于浮点数而不是整数。