Как и шаблоны функции, шаблоны класса начинаются с ключевого слова template
, за которым следует список параметров шаблона. В определении шаблона класса (и его членов) используются параметры шаблона как знакоместа типов или значений, которые будут подставлены при использовании шаблона:
template
public:
typedef T value_type;
typedef typename std::vector
//
Blob();
Blob(std::initializer_list
//
size_type size() const { return data->size(); }
bool empty() const { return data->empty(); }
//
void push_back(const T &t) {data->push_back(t);}
//
void push_back(T &&t) { data->push_back(std::move(t)); }
void pop_back();
//
T& back();
Т& operator[](size_type i); //
private:
std::shared_ptr
//
void check(size_type i, const std::string &msg) const;
}
У шаблона Blob
есть один параметр типа Т
. Он используется везде, где ожидается тип элемента, хранимый классом Blob
. Например, тип возвращаемого значения функции доступа к элементам Blob
определен как Т&
. Когда пользователь создаст экземпляр шаблона Blob
, он использует параметр Т
для замены конкретным типом аргумента шаблона.
За исключением списка параметров шаблона и использования Т
вместо string
, этот класс совпадает с тем, что было определено в разделе 12.1.1 и модифицировано в разделе 12.1.6, а также в главах 13 и 14.
Как уже неоднократно упоминалось, при использовании шаблона класса следует предоставить дополнительную информацию. Как можно теперь утверждать, эта дополнительная информация является списком
Например, чтобы определить тип для шаблона Blob
, следует предоставить тип элемента:
Blob
Blob
Оба объекта, ia
и ia2
, используют ту же специфическую для типа версию шаблона Blob
(т.е. Blob
). Из этих определений компилятор создает экземпляр класса, который эквивалентен следующему:
template <> class Blob
typedef typename std::vector
Blob();
Blob(std::initializer_list
// ...
int& operator[](size_type i);
private:
std::shared_ptr
void check (size_type i, const std::string &msg) const;
};
Когда компилятор создает экземпляр класса из шаблона Blob
, он переписывает его, заменяя каждый экземпляр параметра T
заданным аргументом шаблона, которым в данном случае является int
.
Компилятор создает разный класс для каждого заданного типа элемента:
//
Blob
Blob
Эти определения привели бы к созданию двух разных экземпляров класса: определение names
создает класс Blob
, в котором каждое вхождение Т
заменено на string
. Определение prices
создает класс Blob
, где Т
заменено на double
.
При каждом создании экземпляра шаблона класса получается независимый класс. У типа
Blob
нет никаких отношений с другим типом класса Blob
или специальных прав доступа к его членам.
При чтении кода шаблона класса не следует забывать, что имя шаблона класса не является именем самого класса (см. раздел 3.3). Шаблон класса используется для создания экземпляра класса, при этом всегда используются аргументы шаблона.