Szablony z parametrami domyślnymi to potężny mechanizm programowania ogólnego w C++.
Historia pytania:
Biblioteka STL zaczynała od szablonów. Później pojawiła się możliwość określania wartości domyślnych dla parametrów zarówno funkcji szablonowych, jak i klas, aby uczynić szablony bardziej uniwersalnymi i wspierać rozwijalność kodu.
Problem:
Nieoczywiste konflikty mogą występować, gdy istnieją przeciążenia funkcji zwykłych i szablonowych, a także niejednoznaczności przy specjalizacjach. Parametry domyślne w szablonach mogą zwiększać elastyczność, ale często prowadzą do zagmatwanych błędów kompilacji.
Rozwiązanie:
Lepiej minimalizować liczbę wartości domyślnych w szablonach, zwłaszcza jeśli istnieje nakładanie się z nie-szablonowymi wersjami. Preferencje przy wywołaniu funkcji dają pierwszeństwo dokładnemu dopasowaniu z funkcją zwykłą, a nie szablonową.
Przykład kodu:
template<typename T = int> T multiply(T a, T b = T(2)) { return a * b; } int multiply(int a, int b) { return a + b; }
Wywołanie multiply(5, 4) wybierze funkcję int multiply(int, int), a wywołanie multiply<>(5) wywoła szablon, a b przyjmie wartość 2.
Kluczowe cechy:
Czy można zadeklarować parametry domyślne w kolejnym określeniu funkcji szablonowej?
Nie, wartość domyślna może być podana tylko w jednym miejscu (zwykle w ogłoszeniu), w przeciwnym razie wystąpi błąd kompilacji.
Co się stanie w przypadku niejednoznaczności między szablonem a funkcją nie-szablonową? Jak kompilator wybiera, co wywołać?
Kompilator zawsze będzie preferował funkcję nie-szablonową, jeśli pasuje dokładnie do argumentów. Szablon zostanie wywołany tylko w przypadku braku dokładnego dopasowania.
Czy można podawać wartości domyślne dla nie-typowego parametru szablonu (na przykład dla liczby)?
Tak, na przykład:
template<typename T, int N = 8> class Array { T data[N]; };
Negatywny przypadek
Zadeklarowane zostały zarówno funkcja szablonowa, jak i nie-szablonowa z pasującymi parametrami i wartościami domyślnymi. W jednym module wywołanie działa zgodnie z zamysłem, a w innym niespodziewanie wybierana jest nie ta wersja funkcji.
Zalety:
Wady:
Pozytywny przypadek
Dla nakładających się konfiguracji jasno zadeklarowane różne nazwiska dla funkcji szablonowych i nie-szablonowych, wartości domyślne tylko w jednej z wersji.
Zalety:
Wady: