我有以下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) ) {
...
}
Run Code Online (Sandbox Code Playgroud)
并make
爆炸:
error: call of overloaded 'abs(double)' is ambiguous
Run Code Online (Sandbox Code Playgroud)
也感兴趣:
/usr/include/stdlib.h:785: note: candidates are: int abs(int)
Run Code Online (Sandbox Code Playgroud)
如何指定编译器需要在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)
Run Code Online (Sandbox Code Playgroud)
sbi*_*sbi 48
标头<math.h>
是C std lib标头.它在全局命名空间中定义了很多东西.标头<cmath>
是该标头的C++版本.它在命名空间中定义了基本相同的东西std
.(有一些差异,比如C++版本带有一些函数的重载,但这并不重要.)标题<cmath.h>
不存在.
由于供应商不想维护基本相同标题的两个版本,因此他们想出了在幕后只有一个版本的不同可能性.通常,这是C头(因为C++编译器能够解析它,而相反的方法不起作用),并且C++头只包含它并将所有内容拉入命名空间std
.或者有一些宏观魔法用于解析相同的标题,无论是否namespace std
包裹它.对此添加,在某些环境中,如果标头没有文件扩展名(如编辑器无法突出显示代码等),则会很麻烦.因此,一些供应商将<cmath>
是一个单行,包括一些带有.h
扩展名的其他标题.或一些将映射所有包括匹配<cblah>
到<blah.h>
(其通过宏魔法,成为C++头时__cplusplus
被定义,否则成为C报头)或<cblah.h>
或任何.
这就是为什么在某些平台上,包括那些<cmath.h>
不应该存在的平台,最初会成功的,尽管它可能会使编译器在以后出现故障.
我不知道你使用哪个std lib实现.我想这是GCC附带的那个,但我不知道,所以我无法解释你的情况究竟发生了什么.但它肯定是上述特定于供应商的黑客之一,你包括一个你不应该自己包含的标题.也许它是<cmath>
映射到<cmath.h>
一个你没有定义的特定(一组)宏的那个,所以你最终得到了这两个定义.
但请注意,此代码仍不应编译:
#include <cmath>
double f(double d)
{
return abs(d);
}
Run Code Online (Sandbox Code Playgroud)
abs()
全局命名空间中不应该有一个(它是std::abs()
).然而,根据上述实施技巧,可能存在.稍后移植这样的代码(或者只是尝试用你的供应商的下一个版本编译它不允许这样做)可能非常繁琐,所以你应该留意这一点.
小智 38
它归结为:math.h
来自C
于10年前的创建.在math.h中,由于其原始性质,该abs()
函数"基本上"仅适用于整数类型,如果您想获得double的绝对值,则必须使用fabs()
.当C++被创建时,它就math.h
完成了它cmath
.cmath
本质上是math.h,但对C++进行了改进.它改进了诸如必须区分fabs()
和abs之类的东西,并且仅abs()
针对双精度和整数类型进行了改进.总结一下:使用math.h并使用abs()
整数,fabs()
双精度或使用cmath,只需要abs就可以了(更容易和推荐)
希望这可以帮助任何有同样问题的人!
Nia*_*ang 17
使用fabs()而不是abs(),它是相同的,但对于浮点数而不是整数.
归档时间: |
|
查看次数: |
97472 次 |
最近记录: |