Точно так же конструктор, получающий параметр типа initializer_list
, использует свой параметр типа T
как тип элемента для своего параметра типа initializer_list
:
template
Blob
data(std::make_shared
Подобно стандартному конструктору, этот конструктор резервирует новый вектор. В данном случае этот вектор инициализируется из параметра il
.
Чтобы использовать этот конструктор, следует передать список инициализации, тип элементов которого совместим с типом элемента Blob
:
Blob
Параметр этого конструктора имеет тип initializer_list
. Каждый строковый литерал в списке неявно преобразуется в тип string
.
По умолчанию экземпляр функции-члена шаблона класса создается,
//
Blob
//
for (size_t i = 0; i != squares.size(); ++i)
squares[i] = i*i; //
Этот код создает экземпляр класса Blob
и трех его функций-членов: operator[]()
, size()
и конструктора initializer_list
.
Если функция-член не используется, ее экземпляр не создается. Благодаря этому факту можно создавать экземпляры класса, используя типы, которые не отвечают требованиям для некоторых из операций шаблона (см. раздел 9.2).
Из правила, согласно которому следует предоставить аргументы шаблона при использовании шаблона класса, есть одно исключение. В области видимости самого шаблона класса имя шаблона можно использовать без аргументов:
//
//
template
public:
BlobPtr(): curr(0) { }
BlobPtr(Blob
wptr(a.data), curr(sz) { } T& operator*() const {
auto p = check{curr, "dereference past end");
return (*p)[curr]; //
//
}
//
BlobPtr& operator++(); //
BlobPtr& operator--();
private:
//
std::shared_ptr
check(std::size_t, const std::string&) const;
//
std::weak_ptr
std::size_t curr; //
};
Внимательные читатели, вероятно, обратили внимание на то, что префиксные функции-члены инкремента и декремента шаблона класса BlobPtr
возвращают тип BlobPtr&
, а не BlobPtr
. В области видимости шаблона класса компилятор рассматривает ссылки на сам шаблон так, как будто были подставлены аргументы шаблона, соответствующие собственным параметрам. Таким образом, этот код эквивалентен следующему:
BlobPtr
BlobPtr
При определении функций-членов вне тела шаблона класса следует помнить, что код находится не в области видимости класса, пока не встретилось имя класса (см. раздел 7.4):
//
//
template
BlobPtr
//
//
BlobPtr ret = *this; //
++*this; //
//