Wewnątrz klasy szablonowej kompilator traktuje referencję do tego samego szablonu tak jakby był podany argument dla tego szablonu.
#include <iostream> using namespace std; template <typename T> struct Single { Single& me_one() { return *this; } Single<T>& me_two() { return *this; } std::string show() { return "chain call"; } }; int main() { Single<int> s; cout << s.me_one().me_two().me_two().show() << endl; return 0; }Wynik:
chain callW nowym standardzie, możemy uczynić typ parametryczny przyjacielem klasy.
#include <iostream> using namespace std; template <typename Type> struct Bar { friend Type; protected: std::string show() { return "protected show()"; } }; struct FriendType { void run(Bar<FriendType>& b) { cout << b.show() << endl; } }; int main() { FriendType fry; Bar<FriendType> bar; fry.run(bar); return 0; }Wynik:
protected show()Kompilator domyślnie zakłada że nazwa do której się odwołujemy przez operator zakresu (namespace) nigdy nie jest typem dlatego w takich przypadkach należy używać słowa typename.
template <typename T> typename T::value_type fun(const T& c) { return c.res(); }Wczesne wersje standardu dopuszczały domyślne parametry tylko dla szablonów klasy, w nowym standardzie, można stosować je także dla funkcji.
#include <iostream> using namespace std; template <typename T, typename F = less<T> > int cmp(const T& a, const T&b) { F func = F(); return func(a, b); } int main() { cout << cmp(1, 3) << endl; cout << cmp<int, greater<int>>(1, 3) << endl; return 0; }Wynik:
1 0W dużych systemach, koszt inicjowania tego samego szablonu w wielu plikach, może być bardzo duży. Nowy standard pozwala uniknąć tego narzutu dzięki "explicit instantiation" ~ jednoznaczna konkretyzacja. Kiedy kompilator napotka deklarację szablonu jako extern, nie wygeneruje kodu dla tej konkretyzacji w danym pliku - taka deklaracja obiecuje, że gdzieś w programie będzie użyta non-extern konkretyzacja. Może być kilka deklaracji typu extern, ale zawsze musi być jedna definicja dla tej konkretyzacji.
// kompilator nie wygeneruje kodu w tym pliku extern template class Blob<string>; // kod tej szablonowej metody zostanie wygenerowany w obecnym pliku .o template int compare(const int&, const int&);
Brak komentarzy:
Prześlij komentarz