2011-09-26 10 views
14

Pracuję nad programem klasy C++ dla klasy, a mój kompilator narzeka na "niejednoznaczne" wywołanie funkcji. Podejrzewam, że tak jest, ponieważ istnieje kilka funkcji zdefiniowanych z różnymi parametrami.Jak naprawić "niejednoznaczne" wywołanie funkcji?

Jak mogę powiedzieć kompilatorowi, którego chcę? Oprócz poprawki dla konkretnego przypadku, czy istnieje ogólna zasada, taka jak typowanie, które może rozwiązać tego rodzaju problemy?

Edit:

W moim przypadku Próbowałem nazywając abs() wewnątrz cout oświadczenie, przechodząc w dwóch double s.

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

Edit2:

jestem w tym tych trzech nagłówków:

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

using namespace std; 

Edit3:

Skończyłem program bez tego kodu, ale w interesie śledzenia tego questi dalej, udało mi się odtworzyć problem. Dokładny błąd to:

Wezwanie do "abs" jest niejednoznaczne.

Kompilator oferuje trzy wersje abs, z których każda przyjmuje inny typ danych jako parametr.

+1

Czy mógłbyś pokazać przykład ze swojego kodu? –

+1

To naprawdę zależy od sytuacji. Musisz napisać kod i jeśli błąd kompilatora zawiera które funkcje są kandydatami (ostatnie GCC), które również pomaga. –

+2

Również dobre byłoby, które nagłówki są włączone. – mkb

Odpowiedz

19

Co się stało jest to, że masz włączony <cstdlib> (pośrednio, ponieważ jest zawarty w iostream) wraz z using namespace std;. Ten nagłówek deklaruje dwie funkcje w std o nazwie abs(). Jeden pobiera i zwraca long long, a drugi zwraca long. Dodatkowo jest jeden w globalnej przestrzeni nazw (która zwraca int), która pochodzi z <stdlib.h>.

Aby naprawić: cóż, abs(), który bierze podwójne jest w <cmath>, a to faktycznie daje odpowiedź, którą chcesz!

+4

TL; DR: unikaj 'używania przestrzeni nazw'. –

+0

@MatthieuM., Widziałem ten (sematic) błąd nawet przy użyciu 'std :: abs()' w SDK iOS. Błąd został usunięty, gdy usunąłem 'std ::' i użyłem 'abs()'. – iammilind

+1

Tak, problem jest bardziej związany z automatyczną konwersją typu liczbowego. – mkb

-1

Nie wiem, dlaczego to nie jest wywołanie int wersji z ABS, ale można spróbować rodzaju odlewy wyrażeniu (amountOrdered - amountPaid) jako int tj

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

"Nie wiem, dlaczego nie nazywa się wersji int abs" Czy to możliwe, że 'amountOrdered' i' amountPaid' są podwójne? –

+0

Nie masz pewności, co myślałem! Kompilator @OP jest zdezorientowany, którą wersję wybrać (długa lub podwójna), ponieważ nie jest pewne, czy potrzebuje ona typecast do long lub int z double. Mr .R.Martinho - Myślę, że moje rozwiązanie pomoże kompilatorowi zdecydować, którą wersję wybrać. Więc mam pewną prawidłowość :) –

4

abs funkcja włączone przez <cstdlib> jest przeciążona int i long i long long. Ponieważ jako argument podajesz double, kompilator nie ma dokładnego dopasowania, więc próbuje przekonwertować double na typ akceptowany przez abs, ale nie wie, czy powinien spróbować przekonwertować go na int, long, czy też long long, dlatego jest niejednoznaczna.

Ale prawdopodobnie naprawdę chcesz, aby abs ma double i zwraca double. W tym celu należy dołączyć <cmath>.Ponieważ argument double jest dokładnie taki sam, kompilator nie będzie narzekał.

Wygląda na to, że <cstdlib> zostaje automatycznie dołączony do innych nagłówków, które nie powinny się pojawić. Kompilator powinien dać error: ‘abs’ was not declared in this scope lub coś podobnego.

+0

'abs' nie jest szablonem funkcji. Podanie argumentu szablonu nie zadziała. 'Static_cast (bar)' skompilowałoby (ale nadal dałoby błędną odpowiedź) – mkb

+0

@mkb - Dzięki, zapomniałem, że są po prostu przeciążeniami, a nie specjalnościami funkcji szablonów. Edytował tę część. – JohnPS

2

Spróbuj użyć fabs zdefiniowanej w <cmath>. Jako argumenty przyjmuje wartości float, double i long double. abs jest zdefiniowany zarówno w <cmath> i <cstdlib>. Różnica wynosi abs(int), abs(long) i abs(long long) są zdefiniowane w <cstdlib>, podczas gdy inne wersje są zdefiniowane w <cmath>.

+0

Powszechnym sposobem rozwiązania tego rodzaju błędu jest użycie wersji biblioteki C++ zamiast standardowej biblioteki C, np. Cstdio zamiast stdio.h. Biblioteki C++ mają nazwę z prefiksem "c" i bez ".h" – Andiana

Powiązane problemy