Функция-друг для шаблона типа не является неявной шаблонной функцией,например: template<class T> class task { //... friend void next_time(); friend task<T>* preempt(task<T>*); friend task* prmt(task*); // ошибка //... }; Здесь функция next_time() становится другом всех классов task, акаждый класс task имеет в качестве друга функцию preempt() cсоответствующими типами параметров. Функцию preempt() можноопределить как шаблон типа. template<class T> task<T>* preempt(task<T>* t) { /*... */ } Описание функции prmt() является ошибочным, поскольку типаtask не существует, а есть только специальные шаблонные типыtask<int>, task<record>, и т.д.
R.14.8 Статические члены и переменные
Для каждого шаблонного класса или функции, создаваемых по шаблонутипа, образуется своя копия статических переменных или членов.Рассмотрим пример: template<class T> class X { static T s; //... }; X<int> aa; X<char*> bb; Здесь в классе X<int> есть статический член типа int, а в классеX<char> есть статический член типа char*. Аналогично, в приведенном ниже примере, функция f(int*) имеетстатический член s типа int, а функция f(char**) имеет статическийчлен типа char**: template<class T> f(T* p) { static T s; //... } void g(int a, char* b) { f(&a); f(&b); }
R.15 Обработка особых ситуаций