Дальнейший материал предназначен для разработчиков, использующих Microsoft Visual C++ (MSVC) версий 4-6. В Visual C++ .NET перечисленные проблемы отсутствуют.

<p>Шаблоны функций классов в STL</p>

Допустим, у вас есть два вектора объектов Widget, требуется скопировать объекты Widget из одного вектора в конец другого. Задача решается легко — достаточно воспользоваться интервальной функцией insert контейнера vector:

vector vw1, vw2;

vw1.insert(vw1.end, vw2.begin, vw2.end); // Присоединить к vw1 копию

                                               // объектов Widget из vw2

Аналогичную операцию можно выполнить с контейнерами vector и deque:

vector vw;

deque dw;

vw.insert(vw.end, dw.begin, dw.end); // Присоединить к vw копию

                                           // объектов Widget из dw

Оказывается, эту операцию можно выполнить независимо от того, в каких контейнерах хранятся копируемые объекты. Подходят даже нестандартные контейнеры:

vector vw;

list lw;

vw.insert(vw.begin, lw.begin, lw.end); // Присоединить к vw копию

                                             // объектов Widget из lw

set sw;

vw.insert(vw.begin, sw.begin, sw.end); // Присоединить к vw копию

                                             // объектов Widget из sw

template

 typename Allocator = allocator > // Шаблон нестандартного

 class SpecialContainer{…};          // STL-совместимого контейнера

SpecialContainer scw;

vw.insert(vw.begin, scw.begin, scw.end); // Присоединить к vw копию

                                               // объектов Widget из scw

Подобная универсальность объясняется тем, что интервальная функция insert контейнера range вообще не является функцией в общепринятом смысле. Это шаблон функции контейнера, специализация которого с произвольным типом итератора порождает конкретную интервальную функцию insert. Для контейнера vector шаблон insert объявлен в Стандарте следующим образом:

template >

class vector {

public:

 …

 template

 void insert(iterator position, InputIterator first, InputIterator last);

};

Каждый стандартный контейнер должен поддерживать шаблонную версию интервальной функции insert. Аналогичные шаблоны также обязательны для интервальных конструкторов и для интервальной формы assign (см. совет 5).

<p>MSVC версий 4-6</p>

К сожалению, в реализации STL, входящей в комплект поставки версий 4-6, шаблоны функций не объявляются. Библиотека изначально разрабатывалась для MSVC версии 4, а этот компилятор, как и большинство компиляторов того времени, не обладал поддержкой шаблонов функций классов. При переходе от MSCV4 к MSVC6 поддержка этих шаблонов была включена в компилятор, но вследствие судебных дел, косвенно затрагивавших фирму Microsoft, библиотека оставалась практически в неизменном состоянии.

Поскольку реализация STL, поставляемая с MSVC4-6, предназначалась для компилятора без поддержки шаблонов функций классов, авторы библиотеки имитировали эти шаблоны и заменили их конкретными функциями, которым при вызове передавались итераторы контейнера соответствующего типа. Например, шаблон insert был заменен следующей функцией:

void insert(iterator position,   // "iterator" - тип итератора

 iterator first, iterator last); // для конкретного контейнера

Эта ограниченная форма интервальных функций позволяла выполнить интервальную вставку из vector в vector или из list в list, но смешанные операции (например, вставка из vector в list или из set в deque) не поддерживались. Более того, не поддерживалась даже интервальная вставка (а также конструирование или assign) из vector в vector, поскольку итераторы vector::iterator и vector::iterator относятся к разным типам. В результате следующий фрагмент, принимаемый другими компиляторами, не компилируется в MSVC4-6:

istream_iterator begin(cin), end; // Создать итераторы begin и end

                                          // для чтения объектов Widget

                                          // из cin (см. совет 6).

vector vw(begin, end); // Прочитать объекты Widget

                               // из cin в vw (см. совет 6)

                               // не компилируется в MSVC4-6!

list lw;

Перейти на страницу:

Похожие книги