• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed przeciążanie funkcji w c++ - pytanie

Object Storage Arubacloud
+1 głos
562 wizyt
pytanie zadane 6 marca 2018 w C i C++ przez Jakub 0 Pasjonat (23,120 p.)
zamknięte 8 marca 2018 przez Jakub 0

Witam, mam takie proste i śmieszne funkcje:

void show(int a) {
	std::cout << a << std::endl;
}

void show(double a) {
    std::cout << a << std::endl;
}

void show(char str[]) {
	std::cout << str << std::endl;
}

W zależności od argumentów wywołamy funkcje o odpowiedniej sygnaturze. Albo dla parametru char[], double a czy int a (wiem że może to wszystko nie ma większego sensu ale chce zademonstrować o co mi chodzi). Wywołajmy ją tak:

long int x = 10;
show(x);

//taki sam efekt da:

show(10l); 

//funkcja wywoła się dla parametru typu int 

To że tu mamy long int a nie int w niczym nie przeszkadza. W sumie nie trudno się domyślić że w argumencie podajemy wartość różną od double oraz char* . Dlaczego zatem:

unsigned int x = 10; 

show(x); 

//oraz 

show(10u);

to wywołanie powoduje już błąd że wiele funkcji przeciążonych jest zgodnych z listą argumentów?

Dlaczego dla typu long int kompilator mógł się zdecydować a dla unsigned int już nie?

Podawałem też w argumentach typy short. long long i nie było żadnego problemu...

Serdecznie dziękuje za wytłumaczenie ;)

 

komentarz zamknięcia: już znam wytłumaczenie

1 odpowiedź

+1 głos
odpowiedź 6 marca 2018 przez monika90 Pasjonat (22,940 p.)
wybrane 7 marca 2018 przez Jakub 0
 
Najlepsza
Wywołanie funkcji show z parametrem typu long jest niejednoznaczne. Jeżeli u Ciebie jest inaczej to masz jakiś dziwny kompilator... pewnie MSVC.
komentarz 7 marca 2018 przez Jakub 0 Pasjonat (23,120 p.)
edycja 7 marca 2018 przez Jakub 0

Dziękuje za odpowiedź, jeżeli dobrze zrozumiałem to ustawiłem sobie taki plan w jaki sposób kompilator wybiera funkcję o odpowiedniej sygnaturze wśród wielu przeciążonych:

1. Sprawdza która ma listę parametrów zgodną z podanymi argumentami, np:

show(10);

Domyślnie literał liczbowy jest typu int więc od razu wiadomo o jaką funkcje chodzi (o tą z parametrem int).

2. Jeżeli żadna nie jest zgodna z typami argumentów to kompilator sprawdza do której z nich można wartość rzutować. np: show(1.4f);

Przekazywany argument jest typu float, float możemy rzutować i na int i na double. Takie coś mimo że nam może się wydawać logiczne powoduje błąd. Tak samo jest w tym przypadku z innymi typami przekazywanymi, np: short, long, unsigned (tyle że czasami szczegóły zależą już od kompilatora). Jednak załóżmy że nie mamy tej przeciążonej funkcji:

void show(double a);

Wywołujemy funkcję show tak:

show(10ull);

Podajemy typ unsigned long long ale da się go skonwertować tylko na jedną przeciążoną funkcje z parametrem int ( na funkcje z parametrem char* nie możemy tego rzutować). Wobec tego taki zabieg nie przyniesie teraz błędu (chyba że nadal będzie jeszcze jedna przeciążona funkcja z jakimś parametrem liczbowym (różnym od unsigned long long oczywiście), np double)...

Będę wdzięczny za zweryfikowanie mojego sposobu myślenia :)

1
komentarz 7 marca 2018 przez monika90 Pasjonat (22,940 p.)
edycja 7 marca 2018 przez monika90
Dobrze myślisz. Jeżeli wśród kandydatów jest dokładnie jedna funkcja która jest lepsza od wszystkich innych, to ona zostanie wybrana, jeżeli nie ma, bo np. dwie są równie dobre, to program się nie skompiluje.

Reguły określające które funkcje są lepsze od innych to chyba najbardziej skomplikowana część C++.

Np. jeżeli masz dwie funkcje void f(int); i void f(double);, i tylko te dwie, to:

wywołanie f(1) wywoła f(int), jest to dokładne dopasowanie,

wywołanie f(1.0) wywoła f(double), to też jest dokładne dopasowanie,

wywołanie f(static_cast<short>(1)) wywoła f(int), bo konwersja short->int jest lepsza od short->double,

wywołanie f(1.0f) wywoła f(double), bo konwersja float->double jest lepsza od float->int,

wywołanie f(1L) się nie skompiluje, bo long->int jest równie dobre (albo równie złe) jak long->double,

wywołanie f(1.0L) też się nie skompiluje, bo long double->double jest równie dobre jak long double->int,

podobnie f(1U), f(1UL), f(1LL), f(1ULL),

wywołanie f("abc") się nie skompiluje, bo w ogóle nie ma konwersji z const char[4] na int lub double, tzn. zbiór funkcji-kandydatów jest pusty.
komentarz 8 marca 2018 przez Jakub 0 Pasjonat (23,120 p.)
Dziękuje za obszerne wytłumaczenie. Cóż, kiedy ja podstawiłem w argumencie dla tych trzech funkcji przeciążonych typ float to program się nie skompilował. Ale to już może rzeczywiście zależeć od mojego kompilatora. I tak  żeby chyba uniknąć niepewnych sytuacji wystarczy bardziej sprecyzować funkcje (stworzyć więcej przeciążonych wersji z odpowiednimi argumentami). Tak by kompilator nie musiał się domyślać co na co można rzutować tylko miał wszystko na tacy. (Albo czasami można zastosować po prostu szablony).
komentarz 8 marca 2018 przez monika90 Pasjonat (22,940 p.)
Dziwne że się nie kompiluje, bo MSVC na godbolcie kompiluje i zgodnie ze standardem C++ wybiera double

https://godbolt.org/g/C7iWhV

Podobne pytania

0 głosów
0 odpowiedzi 165 wizyt
0 głosów
1 odpowiedź 212 wizyt
0 głosów
1 odpowiedź 461 wizyt

92,575 zapytań

141,424 odpowiedzi

319,649 komentarzy

61,960 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...