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