[C++] szablony klas i definicje funkcji

diego_maradona
Użytkownik
Użytkownik
Posty: 184
Rejestracja: 16 cze 2010, o 00:59
Płeć: Mężczyzna
Lokalizacja: Kraków
Podziękował: 80 razy

[C++] szablony klas i definicje funkcji

Post autor: diego_maradona »

w temacie 260216.htm
Afish pisze:. No i tak swoją drogą, w nagłówkach zwykło umieszczać się jedynie deklaracje, definicje umieszcza się w plikach cpp (wyjątkiem są szablony, ale to temat na inną bajkę).
Więc zacznijmy tę inną bajkę

Ostatnio pisałem program z szablonem klasy i działał on tylko wtedy gdy umieściłem definicje funkcji w pliku nagłówkowym. Pytanie tylko dlaczego szablony są wyjątkiem? Jak na razie nie widzę w tym sensu...
Afish
Moderator
Moderator
Posty: 2828
Rejestracja: 15 cze 2008, o 15:45
Płeć: Mężczyzna
Lokalizacja: Seattle, WA
Podziękował: 3 razy
Pomógł: 356 razy

[C++] szablony klas i definicje funkcji

Post autor: Afish »

Jak wiadomo, szablon to tylko deklaracja funkcji / klasy. Konkretyzacja szablonu dla konkretnego typu następuje w momencie jawnego wywołania odpowiedniej funkcji / tworzenia obiektu klasy, lub w przypadku jawnego zażądania konkretyzacji. Teraz zastanówmy się nad taką sytuacją: mamy plik szablon.hpp, szablon.cpp i main.cpp. W szablon.hpp mamy deklarację jakiejś funkcji szablonowej przyjmującej jeden typ, w szablon.cpp definicję, a w main.cpp wywołanie z typem int. Plik szablon.cpp załącza szablon.hpp, main.cpp robi to samo (czyli też załącza szablon.hpp). Co się stanie w trakcie kompilacji? Kompilator w trakcie kompilowania maina stwierdzi, że nigdzie nie ma definicji funkcji dla typu int - ma rację, bo w pliku hpp jest tylko deklaracja. Ale nie robi problemu, bo przecież ta definicja może być gdzie indziej - w bibliotekach, w plikach obj itp. Gdy do roboty bierze się linker, to niestety ciągle nigdzie nie ma instancji szablonu dla inta, więc dostajemy błąd. Jak to rozwiązać? szablon.hpp mógłby załączać plik szablon.cpp, co nazywamy modelem włączania. Moglibyśmy w main.cpp dokonać konkretyzacji jawnej. Moglibyśmy też przenieść definicję szablonu do pliku hpp i tak najczęściej się robi. Wtedy w trakcie kompilacji maina kompilator rozwinie szablon i wszystko działa.
Z szablonami zdarzają się też inne cuda - przykładowo jeżeli jakiś szablon oznaczymy jako export, to wtedy kompilator stwierdza, że linker ma się nim zająć, a linker uważa, że to robota kompilatora - mamy sytuację, której nie da się rozwiązać :) Oczywiście to co mówię może być już nieaktualne, bo mamy C++11, a w tej wersji kwestia szablonów miała być mocno uporządkowana, jednak póki co nie ma kompilatorów wspierających nowy standard, więc jest to tylko gdybanie.
ODPOWIEDZ