libreria ejemplos c++ std cmath

c++ - ejemplos - Llamada de sobrecarga ambigua a ABS(doble)



sqr c++ (3)

El encabezado <math.h> es un encabezado C std lib. Define muchas cosas en el espacio de nombres global. El encabezado <cmath> es la versión C ++ de ese encabezado. Define esencialmente las mismas cosas en namespace std . (Hay algunas diferencias, como que la versión de C ++ viene con sobrecargas de algunas funciones, pero eso no importa). El encabezado <cmath.h> no existe.

Dado que los proveedores no quieren mantener dos versiones de lo que esencialmente es el mismo encabezado, surgieron diferentes posibilidades para tener solo uno de ellos detrás de escena. A menudo, ese es el encabezado C (ya que un compilador de C ++ es capaz de analizar eso, mientras que lo contrario no funcionará), y el encabezado C ++ solo lo incluye y lo arrastra todo al espacio de nombres std . O hay algo de macro magia para analizar el mismo encabezado con o sin el namespace std envuelto alrededor o no. A esto se agrega que en algunos entornos es incómodo si los encabezados no tienen una extensión de archivo (como que los editores no resalten el código, etc.). Por lo tanto, algunos proveedores tendrían que <cmath> ser un trazador de líneas, incluyendo algún otro encabezado con la extensión .h . O algunos <cblah> todos incluyen <cblah> a <blah.h> (que, a través de macro magic, se convierte en el encabezado C ++ cuando __cplusplus está definido, y de lo contrario se convierte en el encabezado C) o <cblah.h> o lo que sea.

Esa es la razón por la que en algunas plataformas, incluidas cosas como <cmath.h> , que no debería existir, tendrá éxito inicialmente, aunque podría hacer que el compilador falle espectacularmente más adelante.

No tengo idea de la implementación estándar que usa. Supongo que es el que viene con GCC, pero esto no lo sé, así que no puedo explicar exactamente lo que sucedió en su caso. Pero ciertamente es una combinación de uno de los hacks específicos del proveedor anteriores y usted, incluido un encabezado que no debería haber incluido usted mismo. Tal vez es en el que <cmath> asigna a <cmath.h> un macro (s) específico (conjunto de) que no había definido, de modo que terminó con ambas definiciones.

Sin embargo, tenga en cuenta que este código aún no debe compilarse:

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

No debería haber un abs() en el espacio de nombres global (es std::abs() ). Sin embargo, según los trucos de implementación descritos anteriormente, bien podría existir. Enviar ese código más tarde (o simplemente intentar compilarlo con la próxima versión de su proveedor, que no lo permite) puede ser muy tedioso, por lo que debe vigilarlo.

Tengo el siguiente código 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) ) { ... }

y make estallar en:

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

también de interés:

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

¿Cómo puedo especificar que el compilador necesita llamar a abs () en cmath.h que puede manejar flotantes?

Información del compilador (no estoy seguro si esto importa):

[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)


Use fabs () en lugar de abs (), es lo mismo pero para flotantes en lugar de enteros.


math.h se reduce a esto: math.h es de C y se creó hace más de 10 años. En math.h, debido a su naturaleza primitiva, la función abs() es "esencialmente" solo para tipos enteros y si quería obtener el valor absoluto de un doble, tenía que usar fabs() . Cuando se creó C ++, tomó math.h y lo convirtió en cmath . cmath es esencialmente math.h pero mejorado para C ++. Mejoró cosas como tener que distinguir entre fabs() y abs, y acaba de hacer abs() tanto para tipos dobles como enteros. En resumen: use math.h y use abs() para enteros, fabs() para dobles o use cmath y solo tenga abs para todo (más fácil y recomendado)

Espero que esto ayude a cualquiera que tenga el mismo problema.