2011-09-26 47 views
14

Estoy trabajando en un programa C++ para clase, y mi compilador se queja de una llamada a función "ambigua". Sospecho que esto se debe a que hay varias funciones definidas con diferentes parámetros.¿Cómo arreglo una llamada de función "ambigua"?

¿Cómo puedo decirle al compilador cuál quiero? Aparte de un arreglo específico de caso, ¿existe una regla general, como el encasillado, que podría resolver este tipo de problemas?

Editar:

En mi caso, he intentado llamar abs() interior de una declaración cout, pasando en dos double s.

cout << "Amount is:" << abs(amountOrdered-amountPaid);

Edit2:

Estoy incluyendo estos tres encabezados:

#include <iostream> 
#include <fstream> 
#include <iomanip> 

using namespace std; 

Edit3:

he terminado el programa sin este código, pero con el interés de seguir adelante con esta questi en adelante, he reproducido el problema. El error al pie de la letra es:

Llamar a 'abs' es ambiguo.

El compilador ofrece tres versiones de abs, cada una de las cuales toma un tipo de datos diferente como parámetro.

+1

¿Podría mostrar un ejemplo de su código? –

+1

Realmente depende de la situación. Necesitas publicar el código y si el error del compilador incluye qué funciones son candidatas (lo hacen los GCC recientes) también ayuda. –

+2

También sería bueno qué encabezados están incluidos. – mkb

Respuesta

19

Lo que ha ocurrido es que se ha incluido <cstdlib> (indirectamente, ya que está incluido por iostream) junto con using namespace std;. Este encabezado declara dos funciones en std con el nombre abs(). Uno toma y devuelve long long, y el otro devuelve long. Además, está el que está en el espacio de nombres global (que devuelve int) que proviene de <stdlib.h>.

Para corregir: bueno, el abs() que toma el doble está en <cmath>, ¡y eso realmente le dará la respuesta que desea!

+4

TL; DR: evita 'using namespace'. –

+0

@MatthieuM., He visto este error (sematic) incluso cuando uso 'std :: abs()' en iOS SDK. El error se eliminó cuando eliminé 'std ::' y usé simplemente 'abs()'. – iammilind

+1

Sí, el problema se debe más a la conversión automática de tipo numérico. – mkb

-1

No estoy seguro por qué esto no está llamando a la versión de int abs pero se podría intentar la conversión de tipos de la expresión (amountOrdered - AmountPaid) como int, es decir,

cout <<"Amount is: "<< abs((int)(amountOrdered - amountPaint)); 
+1

"No estoy seguro de por qué esto no está llamando a la versión int de abs" ¿Podría ser porque 'amountOrdered' y' amountPaid' son dobles? –

+0

¡Estás en lo correcto, no estoy seguro de lo que estaba pensando! El compilador @OP confunde qué versión llamar (larga o doble) porque no está seguro si necesita encasillar a largo o int desde doble. Mr. R. Martinho - Creo que mi solución ayudará al compilador a decidir qué versión llamar. Así que de alguna manera estoy en lo cierto :) –

4

La función abs incluido por <cstdlib> está sobrecargado para int y long y long long. Como usted da un double como argumento, el compilador no tiene un ajuste exacto, por lo que intenta convertir el double en un tipo que abs acepta, pero no sabe si debe intentar convertirlo a int, long, o long long, por lo tanto, es ambiguo.

Pero es probable que realmente desee el abs que toma un y devuelve un double. Para esto, debe incluir <cmath>.Como el argumento double coincide exactamente, el compilador no se quejará.

Parece que <cstdlib> se incluye automáticamente cuando incluye los otros encabezados que no deberían suceder. El compilador debería haber dado error: ‘abs’ was not declared in this scope o algo similar.

+0

'abs' no es una plantilla de función. Dar un argumento de plantilla no funcionará. Un 'static_cast (barra)' compilaría (pero aún así daría una respuesta incorrecta) – mkb

+0

@mkb - Gracias, olvidé que son simplemente sobrecargas, no funciones especiales de la plantilla. Editado esa parte. – JohnPS

2

Intente utilizar fabs definido en <cmath>. Se necesitan float, double y long double como argumentos. abs se define tanto en <cmath> como en <cstdlib>. La diferencia es abs(int), abs(long) y abs(long long) se definen en <cstdlib>, mientras que otras versiones se definen en <cmath>.

+0

Una solución común para corregir este tipo de error es utilizar la versión C++ de la biblioteca en lugar de la biblioteca C estándar, por ejemplo: cstdio en lugar de stdio.h. Las bibliotecas de C++ tienen nombre con el prefijo 'c' y no '.h' – Andiana

Cuestiones relacionadas