2013-08-09 27 views
8

Z tego co wiem, przy wybieraniu między dwoma kandydującymi funkcjami kompilator będzie preferował ten, w którym jego najsłabszy mecz jest silniejszy. Na przykład jeśli mam:Przeciążanie rozdzielczości

void boo(int i, char c); 
void boo(double d, int i); 

dla następującego kodu:

float f = 1.0; 
char c = 'c'; 
boo(f,c); 

drugi boo powinny być preferowane, ponieważ jego najsłabszy mecz jest promocja podczas gdy pierwsza jest standardowy typ konwersji.

Ale gdy próbuję go (używając gcc) skompilować, otrzymuję:

error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second.

Jakieś pomysły?

+14

mam pomysł. Odczytaj ten komunikat o błędzie, aż stanie się jasne, że standard C++ mówi, że jest to niejednoznaczne. –

+14

+1 dla programisty, który napisał komunikat o błędzie. – JNL

Odpowiedz

12

Twoje zrozumienie rozdzielczości przeciążenia jest nieprawidłowe. Ogólna reguła (w przypadku więcej niż jednego argumentu) polega na wybraniu funkcji, dla której przynajmniej jeden argument jest lepszy (nie ma znaczenia, o ile jest lepszy), a żaden z pozostałych nie jest gorszy. Innymi słowy, kompilator przetwarza każdy argument osobno, tworząc dla niego zestaw "najlepszych dopasowań". Po tym zajmuje połączenie tych zestawów: jeśli przecięcie zawiera dokładnie jedną funkcję , wygrywasz. W przeciwnym razie jest niejednoznaczny.

+0

Chociaż nie powinienem porównywać C++ z java, ale czy jest jakaś różnica w ich przeciążającym procesie sprawdzania - tak jak powyżej C++ niejednoznaczny fragment kodu działa w Javie (promowane typy jeden wykonuje - tj. "Double int" jeden – exexzian

+0

tutaj działa kod w java - http://ideone.com/8brQbE – exexzian

+0

dzięki! (Chyba chodziło ci o skrzyżowanie, a nie związek) – user2668673

0

Załóżmy, że wywołałeś funkcję f. Myślę, że proces usuwania przeciążenia jest następujący: 1. Tworzenie zestawu funkcji kandydujących. Ten zestaw funkcji zawiera wszystkie funkcje o nazwie f, do których można uzyskać dostęp z miejsca, w którym wywołałeś f(). 2. Tworzenie zestawu opłacalnych funkcji. Ten zestaw funkcji jest podzbiorem funkcji kandydujących, dla których liczba parametrów każdej realnej funkcji jest zgodna z liczbą argumentów użytych do wywołania funkcji f(). 3. Wybiera najlepszą możliwą funkcję. Najlepszą możliwą do zastosowania funkcją jest ta, której wszystkie parametry mają niejawne sekwencje konwersji o lepszej lub równej pozycji niż wszystkie inne funkcjonalne funkcje. Jeśli jest więcej lub mniej niż jeden (niezupełnie jeden), wystąpi błąd kompilacji. Poniższy przykład ilustruje to ładnie:

class cat 
{ 
public: 
    cat(int); 
}; 

void func(int, int, int, cat) 
{ 
    std::cout << 1 << std::endl; 
} 
void func(int, int, double, double) 
{ 
    std::cout << 2 << std::endl; 
} 

int main() 
{ 
    func(1,2,3,4); 
} 

Ten kod generuje błąd kompilacji (VS) lub ostrzeżenia (g ++).

Poniższa będzie działał poprawnie (druk 1):

void func(int, int, int, double) 
{ 
     std::cout << 1 << std::endl; 
} 
void func(int, double, double, double) 
{ 
     std::cout << 2 << std::endl; 
} 

int main() 
{ 
     func(1,2,3,4); 
}