string
и wstring
Все, что говорится о контейнере string
, в равной степени относится и к wstring
, его аналогу с расширенной кодировкой символов. Соответственно, любые упоминания о связи между string
и char
или cha
относятся и к связи между wstring
и wchar_t
или wchar_t*
. Иначе говоря, отсутствие специальных упоминаний о строках с расширенной кодировкой символов не означает, что в STL они не поддерживаются. Контейнеры string
и wstring
являются специализациями одного шаблона basic_string
.
Терминология
Данная книга не является учебником начального уровня по STL. Предполагается, что читатель уже владеет основными материалом. Тем не менее следующие термины настолько важны, что я счел необходимым особо выделить их.
•Контейнеры vecto
•Итераторы делятся на пять категорий в соответствии с поддерживаемыми операциями. istream_iterator
и ostream_iterator
соответственно.
list
.
vecto
string
и deque
. В массивах функциональность итераторов произвольного доступа обеспечивается указателями.
•Любой класс, перегружающий оператор вызова функции (то есть operator
•Функции bind1st
и bind2nd
называются
Революционным новшеством STL являются гарантии сложности, то есть ограничения объема работы, выполняемой любыми операциями STL. Таким образом, программист может сравнить относительную эффективность нескольких решений в зависимости от платформы STL. Гарантии сложности выражаются в виде функции от количества элементов в контейнере или интервале
•Операция с
Термин «постоянная сложность» не стоит воспринимать буквально. Он означает не то, что время выполнения операции остается строго постоянной величиной, а лишь то, что оно не зависит от
•Операции с
•Время, необходимое для выполнения операций с count
работает с линейной сложностью, поскольку он должен просмотреть каждый элемент в заданном интервале. Если интервал увеличивается в три раза, объем работы тоже увеличивается втрое, поэтому операция занимает в три раза больше времени.
Как правило, операции с постоянной сложностью выполняются быстрее, чем операции с логарифмической сложностью, а последние выполняются быстрее операций с линейной сложностью. Этот принцип особенно четко выполняется для больших значений
И последнее замечание по поводу терминологии: вспомните, что каждый элемент контейнеров map
и multimap
состоит из двух компонентов. Я обычно называю первый компонент
map<string,double> m;
ключ относится к типу string
, а ассоциированное значение — к типу double
.
Примеры
Книга содержит множество примеров. Все примеры комментируются по мере их приведения, и все же кое-что следует пояснить заранее.
Из приведенного выше примера с map
видно, что я обычно опускаю директивы #include
и игнорирую тот факт, что компоненты STL принадлежат пространству имен std. Полное определение m должно было выглядеть так:
#include <map>
#include <string>
using std::map;
using std::string;
map<string. double> m;
Но я предпочитаю оставить в примере лишь самое существенное. При объявлении формального параметра-типа шаблона вместо class
используется ключевое слово typename
. Иначе говоря, вместо конструкции вида
template <class Т>
class Widget{...};
я использую конструкцию
template <typename Т>
class Widget{...};
В данном контексте ключевые слова class
и typename
эквивалентны, но мне кажется, что слово typename
более четко выражает важную мысль: подходит class
— пожалуйста. Выбор между typename
и class
в этом контексте зависит только от стиля.
Однако в других контекстах стиль не является единственным фактором. Во избежание потенциальных неоднозначностей лексического анализа (я избавлю вас от подробностей) имена типов, зависящие от формальных параметров шаблона, должны предваряться ключевым словом typename
. Такие типы называются
template <typename С>
bool latGreaterThanFirst(const С& container)
{
if(container.empty()) return false:
typename C::const_iterator begin(container.begin());
typename C::const_iterator end(container.end());
return *--end > *begin;
}
В этом примере локальные переменные begin
и end
относятся к типу С::const_iterator
С:: const_iterator
является зависимым, перед ним должно стоять ключевое слово typename
. Некоторые компиляторы принимают код без typename
, но такой код не переносится на другие платформы.
Надеюсь, вы обратили внимание на жирный шрифт в приведенных примерах. Выделение должно привлечь ваше внимание к особенно важным фрагментам кода. Нередко таким образом подчеркиваются различия между похожими примерами, как, например, при демонстрации двух разных способов объявления параметра Т в примере Widget
. Аналогичным образом помечаются и важные блоки на рисунках. Например, на диаграмме из совета 5 таким образом помечаются два указателя, изменяемые при вставке нового элемента в список.
В книге часто встречаются параметры lhs
и rhs
. Эти сокращения означают «left-hand side» («левая сторона») и «right-hand side» («правая сторона») соответственно, они особенно удобны при объявлении операторов. Пример из совета 19: