2011-09-26 14 views
14

Sto lavorando a un programma C++ per la classe e il mio compilatore si sta lamentando di una chiamata di funzione "ambigua". Sospetto che ciò avvenga perché esistono diverse funzioni definite con parametri diversi.Come posso risolvere una chiamata di funzione "ambigua"?

Come posso dire al compilatore quale voglio? Oltre a una correzione specifica del caso, esiste una regola generale, come la tipizzazione, che potrebbe risolvere questo tipo di problemi?

Edit:

Nel mio caso, ho provato a chiamare abs() all'interno di una dichiarazione cout, passando in due double s.

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

Edit2:

sto compresi questi tre intestazioni:

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

using namespace std; 

Edit3:

ho finito il programma senza questo codice, ma nell'interesse di seguire con questi argomenti su, ho riprodotto il problema. L'errore letterale è:

La chiamata a "add" è ambigua.

Il compilatore offre tre versioni di abs, ognuna con un diverso tipo di dati come parametro.

+1

Mostreresti un esempio dal tuo codice? –

+1

Dipende davvero dalla situazione. È necessario inserire il codice e se l'errore del compilatore include quali funzioni sono candidate (i GCC recenti) possono essere d'aiuto. –

+2

Anche le intestazioni sono buone. – mkb

risposta

19

cosa è successo è che hai inserito <cstdlib> (indirettamente, dal momento che è incluso da iostream insieme a using namespace std;. Questa intestazione dichiara due funzioni in std con il nome abs(). Uno prende e restituisce long long e l'altro restituisce long. Inoltre, c'è quello nel namespace globale (che restituisce int) che viene da <stdlib.h>.

Per risolvere: bene, il abs() che prende il doppio è in <cmath> e che effettivamente ti darà la risposta che vuoi!

+4

TL; DR: evitare 'using namespace'. –

+0

@MatthieuM., Ho visto questo errore (sematico) anche quando si utilizza 'std :: abs()' in iOS SDK. L'errore è stato rimosso quando ho rimosso 'std ::' e usato solo 'abs()'. – iammilind

+1

Sì, il problema è più dovuto alla conversione automatica del tipo numerico. – mkb

-1
Non

sicuro perché questo non sta chiamando la versione int di abs, ma si potrebbe provare tipo di getto l'espressione (amountOrdered - amountPaid) come int vale a dire

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

"Non sei sicuro del motivo per cui questo non sta chiamando la versione int di abs" Potrebbe essere la causa 'amountOrdered' e' amountPaid' sono doppi? –

+0

Non sei sicuro di cosa stavo pensando! Il compilatore @OP è confuso quale versione chiamare (lunga o doppia) perché non è sicura se è necessario digitare a lungo o int da doppio. MrRartinho - Credo che la mia soluzione aiuterà il compilatore a decidere quale versione chiamare. Quindi in qualche modo sto corretto :) –

4

La funzione abs incluso da <cstdlib> è sovraccarico per int e long e long long. Dato che l'argomento è double, il compilatore non ha un adattamento esatto, quindi tenta di convertire double in un tipo accettato da abs, ma non sa se deve provare a convertirlo in int, long o long long, quindi è ambiguo.

Ma probabilmente si desidera veramente lo abs che prende uno double e restituisce un double. Per questo è necessario includere <cmath>.Poiché l'argomento double corrisponde esattamente, il compilatore non si lamenterà.

Sembra che <cstdlib> venga incluso automaticamente quando si includono le altre intestazioni che non dovrebbero accadere. Il compilatore dovrebbe avere dato error: ‘abs’ was not declared in this scope o qualcosa di simile.

+0

'abs' non è un modello di funzione. Dare un argomento modello non funzionerà. Un 'static_cast (bar)' potrebbe compilare (ma dare ancora una risposta errata) – mkb

+0

@mkb - Grazie, ho dimenticato che sono semplicemente sovraccariche e non funzioni di specializzazione di template. Modificato quella parte. – JohnPS

2

Provare a utilizzare fabs definito in <cmath>. Ci vogliono float, double e long double come argomenti. abs è definito sia in <cmath> e <cstdlib>. La differenza è abs(int), abs(long) e abs(long long) sono definite in <cstdlib> mentre altre versioni sono definite in <cmath>.

+0

Una soluzione comune per correggere questo tipo di errore è utilizzare la versione C++ della libreria anziché la libreria C standard, ad esempio: cstdio invece di stdio.h. Le librerie C++ hanno il nome con il prefisso 'c' e no '.h' – Andiana

Problemi correlati