Шаблоны классов

Определение

Шаблон класса -- это обобщённый тип, зависящий от параметров шаблона.

template <class T>
class Stack{
    //...
};

Шаблоны классов отличаются от шаблонов функций тем, что их нельзя инстанцировать неявно, т.к. нет "вызова" класса.

MyStack<int> s1;
MyStack<string> s2;

Отметим, что s1 и s2 -- это экземпляры разных типов, они никак не родственны друг другу в смысле ООП.

Не стоит путать экземпляр класса (объект) и специализацию класса (тип). Экземпляр для шаблонного класса создать невозможно, экземпляр можно сделать только для конкретной его специализации:

MyStack s1; -- так делать нельзя!

Методы шаблонных классов являются (должны являться) шаблонными функциями, и это особенно заметно когда их тела описываются вне тела члена класса.

#include <iostream>
using namespace std;

template <class T>
class Encapsulator;

template <class T>
ostream & operator<< (ostream &out, Encapsulator<T> right);

template <class T>
class Encapsulator {
    T val;
public:
    Encapsulator(T _val):val(_val) {}
    Encapsulator<T> operator* (Encapsulator<T> right) const;
    Encapsulator<T> operator+ (Encapsulator<T> right) const;
friend ostream & operator<< <T> (ostream &out, Encapsulator<T> right);
};

template <class T>
Encapsulator<T> Encapsulator<T>::operator* (Encapsulator<T> right) const
{
    return Encapsulator<T>(val*right.val);
}

template <class T>
Encapsulator<T> Encapsulator<T>::operator+ (Encapsulator<T> right) const
{
    return Encapsulator<T>(val + right.val);
}

template <class T>
ostream & operator<< (ostream &out, Encapsulator<T> right)
{
    out << right.val;
    return out;
}

int main()
{
    Encapsulator<int> a(5);
    Encapsulator<string> b("asdf");

    cout << a << endl;
    cout << b << endl;
    cout << (a + a) << endl;
    cout << (b + b) << endl;
    cout << (a*a) << endl;

    return 0;
}

Опыт показал, что бинарные операторы для шаблонных классов лучше описывать как методы, а не как дружественные функции.

Перегрузка оператора вывода в поток потребовала предварительного объявления дружественной функции.