Chociaż nie jest zalecane, w C++ (podobnie jak w jego poprzedniku, C) możliwe jest wciąż tworzenie funkcji z nieokreśloną liczbą argumentów. Najbardziej znanym przykładem jest oczywiście printf
:
Nie wszyscy wiedzą jednak, że zmienną liczbą parametrów mogą mieć też makra (co nazywa się po angielsku variadic macros). Deklaruje się je wtedy w bardzo podobny sposób jak funkcje, też używając wielokropka:
Żeby jednak dostać się do ‘listy argumentów’ makra, używamy specjalnego identyfikatora __VA_ARGS__
. W jego miejsce zostaną podstawione wszystkie podane parametry (z wyjątkiem pierwszego), oddzielone przecinkami tak, jak w oryginalnym “wywołaniu” makra.
Do czego może się to przydać? Jak widać powyżej, za pomocą takich makr możemy na przykład opakowywać wywołania funkcji ze zmienną liczbą argumentów – jak w powyższym przykładzie z logowaniem. Prawdopodobnie mogą być one przydatne także w implementacji jakiejś formy delegatów w C++, zwłaszcza jeśli chodzi o sposób ich wywoływania. Istnieje też ciekawa technika, pozwalająca na tworzenie (w C99 i późniejszych wersjach C/C++) funkcji z nieokreśloną liczbą argumentów, ale z zachowaną kontrolą ich typów.
Po co marka skoro doskonale sie do tego nadaja funkcje iniline. Po co wielokoropek skoro doskonale sie do tego nadaje std::vector.
Bo korzystanie z nietypowych narzędzi językowych daje twojej aplikacji +10 do Szpanu ;P
bo są takie divice’y na których takie rozwiązanie będzie lepsze, ponieważ niektóre części języka mogą nie być wpełni dobrze (efektywnie) zaimplementowane w pewnych kompilatorach :)
Dobre to jest! Nie znałem tego. Czy to jest możliwość C++, czy rozszerzenie Microsoftu?
Tak, to jest część standardu C99, więc i C++ też. Obsługa tego słowa różni się jednak trochę między kompilatorami. Dotyczy to głównie sytuacji, gdy pod __VA_ARGS__ nie daje się podstawić żadnego argumentu i w rozwinięciu makra może zostać przecinek, powodujący błąd składniowy. W VC++ jest on wtedy automatycznie usuwany; w GCC trzeba użyć ## między przecinkiem a __VA_ARGS__.
Uuu ostre nawiasy zostały obcięte. :)
// (by Xion) – poprawione :)
Przykład Miśka zawiera friend T w deklaracji klasy co nie jest standardowym C++.