2. Мэтью Уилсон
EXTENDED STL, VOLUME 1
Upper Saddle River, NJ • Boston • Indianapolis • San Francisco
New York • Toronto • Montreal • London • Munich • Paris • Madrid
Capetown • Sydney • Tokyo • Singapore • Mexico City
Collections and Iterators
5. Содержание
Предисловие ...................................................................................... 22
Цели ..................................................................................................... 22
Предмет обсуждения ........................................................................... 23
Организация книги ............................................................................... 24
Дополнительные материалы ................................................................ 25
Благодарности .................................................................................. 26
Об авторе ............................................................................................. 28
Пролог................................................................................................... 29
Дихотомия объекта исследования ....................................................... 29
Принципы программирования в системе UNIX ..................................... 30
Семь признаков успешных библиотек на C++....................................... 31
Эффективность ............................................................................... 31
Понятность и прозрачность ............................................................. 33
Выразительные возможности .......................................................... 34
Надежность ..................................................................................... 36
Гибкость .......................................................................................... 37
Модульность ................................................................................... 38
Переносимость ............................................................................... 38
Поиск компромиссов: довольство тем, что имеешь,
диалектизм и идиомы .......................................................................... 39
Примеры библиотек ............................................................................. 40
STLSoft ............................................................................................ 41
Подпроекты STLSoft ........................................................................ 41
Boost ............................................................................................... 43
Open RJ ........................................................................................... 43
Pantheios ......................................................................................... 43
recls ................................................................................................. 44
Типографские соглашения ........................................................... 45
Шрифты ............................................................................................... 45
. . . сравни . . . ....................................................................................... 45
Предварительное вычисление концевого итератора ........................... 46
Квалификация типа вложенного класса................................................ 46
6. 66666 СодержаниеСодержаниеСодержаниеСодержаниеСодержание
NULL..................................................................................................... 47
Имена параметров шаблона ................................................................ 47
Имена типов членов и типов в области видимости пространства имен ... 48
Соглашения о вызове........................................................................... 48
Концевые итераторы ............................................................................ 48
Пространство имен для имен из стандартной библиотеки C ................ 49
Адаптеры классов и адаптеры экземпляров ......................................... 49
Имена заголовочных файлов................................................................ 49
Часть I. Основы.................................................................................. 50
Глава 1. Стандартная библиотека шаблонов ........................ 52
1.1. Основные понятия ......................................................................... 52
1.2. Контейнеры ................................................................................... 53
1.2.1. Последовательные контейнеры ............................................. 53
1.2.2. Ассоциативные контейнеры ................................................... 54
1.2.3. Непрерывность памяти .......................................................... 54
1.2.4. swap ....................................................................................... 54
1.3. Итераторы ..................................................................................... 55
1.3.1. Итераторы ввода ................................................................... 55
1.3.2. Итераторы вывода ................................................................. 56
1.3.3. Однонаправленные итераторы............................................... 57
1.3.4. Двунаправленные итераторы ................................................. 57
1.3.5. Итераторы с произвольным доступом ................................... 58
1.3.6. Оператор выбора члена ......................................................... 58
1.3.7. Предопределенные адаптеры итераторов ............................. 60
1.4. Алгоритмы ..................................................................................... 61
1.5. Объекты функции .......................................................................... 62
1.6. Распределители ............................................................................ 62
Глава 2. Концепции расширения STL, или Как STL
ведет себя при встрече с реальным миром........................... 63
2.1. Терминология................................................................................ 63
2.2. Наборы .......................................................................................... 64
2.2.1. Изменчивость ........................................................................ 66
2.3. Итераторы ..................................................................................... 67
2.3.1. Изменчивость ........................................................................ 68
2.3.2. Обход ..................................................................................... 68
2.3.3. Определение характеристик на этапе компиляции ................ 68
2.3.4. Категория ссылок на элементы .............................................. 68
2.3.5. Общее и независимое состояние ........................................... 68
2.3.6. Не пересмотреть ли классификацию итераторов? ................. 69
7. 77777СодержаниеСодержаниеСодержаниеСодержаниеСодержание
Глава 3. Категории ссылок на элементы ................................ 71
3.1. Введение ....................................................................................... 71
3.2. Ссылки в C++ ................................................................................. 71
3.2.1. Ссылки на элементы STL контейнеров ................................... 72
3.3. Классификация ссылок на элементы ............................................. 73
3.3.1. Перманентные ....................................................................... 73
3.3.2. Фиксированные ..................................................................... 74
3.3.3. Чувствительные ..................................................................... 74
3.3.4. Недолговечные ...................................................................... 76
3.3.5. Временные по значению ........................................................ 78
3.3.6. Отсутствующие ...................................................................... 79
3.4. Использование категорий ссылок на итераторы............................ 79
3.4.1. Определение категории на этапе компиляции ....................... 79
3.4.2. Как компилятор может помочь избежать неопределенного
поведения итератора ...................................................................... 80
3.5. Определение оператора operator >() ........................................... 81
3.6. Еще о категориях ссылок на элементы .......................................... 82
Глава 4. Забавная безвременная ссылка ............................... 83
Глава 5. Принцип DRY SPOT ......................................................... 85
5.1. Принцип DRY SPOT в C++ ............................................................... 85
5.1.1. Константы .............................................................................. 85
5.1.2. Оператор dimensionof() .......................................................... 86
5.1.3. Порождающие функции ......................................................... 87
5.2. Когда в C++ приходится нарушать принцип DRY SPOT ................... 87
5.2.1. Родительские классы ............................................................. 87
5.2.2. Типы значений, возвращаемых функциями ............................ 88
5.3. Замкнутые пространства имен ...................................................... 89
Глава 6. Закон дырявых абстракций ........................................ 91
Глава 7. Программирование по контракту ............................. 93
7.1. Виды контроля............................................................................... 93
7.2. Механизмы контроля ..................................................................... 95
Глава 8. Ограничения ..................................................................... 96
8.1. Поддержка со стороны системы типов .......................................... 96
8.2. Статические утверждения ............................................................. 97
8. 88888 СодержаниеСодержаниеСодержаниеСодержаниеСодержание
Глава 9. Прокладки .......................................................................... 99
9.1. Введение ....................................................................................... 99
9.2. Основные прокладки ................................................................... 100
9.2.1. Атрибутные прокладки ......................................................... 100
9.2.2. Конвертирующие прокладки ................................................ 101
9.3. Составные прокладки .................................................................. 104
9.3.1. Прокладки строкового доступа ............................................ 104
Глава 10. Утка и гусь, или Занимательные основы
частичного структурного соответствия................................. 108
10.1. Соответствие............................................................................. 108
10.1.1. Соответствие по имени ...................................................... 108
10.1.2. Структурное соответствие ................................................. 110
10.1.3. Утка и гусь .......................................................................... 111
10.2. Явное семантическое соответствие .......................................... 113
10.2.1. Концепции.......................................................................... 113
10.2.2. Пометка с помощью типов членов ..................................... 114
10.2.3. Прокладки .......................................................................... 114
10.3. Пересекающееся соответствие ................................................. 115
Глава 11. Идиома RAII .................................................................. 116
11.1. Изменчивость ............................................................................ 116
11.2. Источник ресурса ...................................................................... 116
Глава 12. Инструменты для работы с шаблонами ............ 118
12.1. Характеристические классы ...................................................... 118
12.1.1. Класс base_type_traits......................................................... 120
12.1.2. Класс sign_traits.................................................................. 121
12.1.3. Свойства типа: мини характеристики ................................ 122
12.1.4. Класс is_integral_type .......................................................... 122
12.1.5. Класс is_signed_type ........................................................... 124
12.1.6. Класс is_fundamental_type .................................................. 124
12.1.7. Класс is_same_type ............................................................. 125
12.2. Генераторы типов ...................................................................... 126
12.2.1. Класс stlsoft::allocator_selector ........................................... 126
12.3. Истинные typedef ....................................................................... 127
Глава 13. Выводимая адаптация интерфейса:
адаптации типов с неполными интерфейсами
на этапе компиляции .................................................................... 128
13.1. Введение ................................................................................... 128
9. СодержаниеСодержаниеСодержаниеСодержаниеСодержание 99999
13.2. Адаптация типов с неполными интерфейсами ........................... 129
13.3. Адаптация неизменяемых наборов ............................................ 130
13.4. Выводимая адаптация интерфейса ........................................... 131
13.4.1. Выбор типа......................................................................... 132
13.4.2. Распознавание типа ........................................................... 133
13.4.3. Исправление типа .............................................................. 134
13.5. Применение IIA к диапазону....................................................... 136
Глава 14. Гипотеза Хенни, или Шаблоны атакуют!........... 138
Глава 15. Независимые автономии друзей equal() ......... 140
15.1. Опасайтесь неправильного использования
функций друзей, не являющихся членами ......................................... 140
15.2. Наборы и их итераторы.............................................................. 143
Глава 16. Важнейшие компоненты.......................................... 144
16.1. Введение ................................................................................... 144
16.2. Класс auto_buffer ....................................................................... 144
16.2.1. Это не контейнер! .............................................................. 145
16.2.2. Интерфейс класса .............................................................. 146
16.2.3. Копирование ...................................................................... 147
16.2.4. Воспитанные распределители идут последними ................ 147
16.2.5. Метод swap() ...................................................................... 148
16.2.6. Производительность .......................................................... 148
16.3. Класс filesystem_traits ................................................................ 149
16.3.1. Типы члены ........................................................................ 149
16.3.2. Работа со строками ............................................................ 150
16.3.3. Работа с именами из файловой системы ........................... 150
16.3.4. Операции с состоянием объектов файловой системы ....... 153
16.3.5. Операции управления файловой системой ........................ 154
16.3.6. Типы возвращаемых значений и обработка ошибок .............. 154
16.4. Класс file_path_buffer ................................................................. 154
16.4.1. Класс basic_?? .................................................................... 156
16.4.2. UNIX и PATH_MAX ................................................................ 157
16.4.3. Windows и MAX_PATH .......................................................... 158
16.4.4. Использование буферов .................................................... 159
16.5. Класс scoped_handle.................................................................. 159
16.6. Функция dl_call() ........................................................................ 160
Часть II. Наборы .............................................................................. 163
Глава 17. Адаптация API glob ..................................................... 167
17.1. Введение ................................................................................... 167
10. 1010101010 СодержаниеСодержаниеСодержаниеСодержаниеСодержание
17.1.1. Мотивация ......................................................................... 167
17.1.2. API glob .............................................................................. 169
17.2. Анализ длинной версии ............................................................. 171
17.3. Класс unixstl::glob_sequence ...................................................... 174
17.3.1. Открытый интерфейс ......................................................... 174
17.3.2. Типы члены ........................................................................ 175
17.3.3. Переменные члены ............................................................ 176
17.3.4. Флаги ................................................................................. 176
17.3.5. Конструирование ............................................................... 179
17.3.6. Размер и доступ к элементам ............................................. 180
17.3.7. Итерация ............................................................................ 181
17.3.8. Метод init_glob_() ............................................................... 182
17.4. Анализ короткой версии ............................................................ 187
17.5. Резюме ...................................................................................... 188
Глава 18. Интерлюдия: конфликты в конструкторах
и дизайн, который не то чтобы плох, но мало
подходит для беспрепятственного развития...................... 190
Глава 19. Адаптация API opendir/readdir............................... 193
19.1. Введение ................................................................................... 193
19.1.1. Мотивация ......................................................................... 193
19.1.2. API opendir/readdir.............................................................. 195
19.2. Анализ длинной версии ............................................................. 195
19.3. Класс unixstl::readdir_sequence .................................................. 197
19.3.1. Типы и константы члены .................................................... 199
19.3.2. Конструирование ............................................................... 200
19.3.3. Методы, относящиеся к размеру и итерированию ............. 200
19.3.4. Методы доступа к атрибутам.............................................. 202
19.3.5. const_iterator, версия 1 ....................................................... 202
19.3.6. Использование версии 1 .................................................... 206
19.3.7. const_iterator, версия 2: семантика копирования ................ 207
19.3.8. operator ++() ....................................................................... 210
19.3.9. Категория итератора и адаптируемые типы члены ............ 210
19.3.10. operator >() ..................................................................... 211
19.3.11. Поддержка флагов fullPath и absolutePath ........................ 211
19.4. Альтернативные реализации ..................................................... 214
19.4.1. Хранение элементов в виде мгновенного снимка ............... 214
19.4.2. Хранение элементов в виде итератора............................... 215
19.5. Резюме ...................................................................................... 215
Глава 20. Адаптация API FindFirstFile/FindNextFile............ 217
20.1. Введение ................................................................................... 217
11. 1111111111СодержаниеСодержаниеСодержаниеСодержаниеСодержание
20.1.1. Мотивация ......................................................................... 217
20.1.2. API FindFirstFile/FindNextFile ............................................... 220
20.2. Анализ примеров ....................................................................... 222
20.2.1. Длинная версия .................................................................. 222
20.2.2. Короткая версия................................................................. 223
20.2.3. Точки монтирования и бесконечная рекурсия .................... 224
20.3. Проектирование последовательности ....................................... 225
20.4. Класс winstl::basic_findfile_sequence .......................................... 226
20.4.1. Интерфейс класса .............................................................. 226
20.4.2. Конструирование ............................................................... 228
20.4.3. Итерация ............................................................................ 229
20.4.4. Обработка исключений ...................................................... 229
20.5. Класс winstl::basic_findfile_sequence_const_iterator .................... 231
20.5.1. Конструирование ............................................................... 233
20.5.2. Метод find_first_file_() ......................................................... 235
20.5.3. operator ++() ....................................................................... 237
20.6. Класс winstl::basic_findfile_sequence_value_type ......................... 244
20.7. Прокладки ................................................................................. 246
20.8. А где же шаблонные прокладки и конструкторы? ....................... 247
20.9. Резюме ...................................................................................... 247
20.10. Еще об обходе файловой системы с помощью recls................. 248
Глава 21. Интерлюдия: о компромиссе между
эффективностью и удобством использования:
обход каталогов на FTP сервере.............................................. 249
21.1. Класс inetstl::basic_findfile_sequence.......................................... 250
21.2. Класс inetstl::basic_ftpdir_sequence............................................ 251
Глава 22. Перебор процессов и модулей ............................. 254
22.1. Характеристики набора ............................................................. 255
22.2. Класс winstl::pid_sequence ......................................................... 255
22.2.1. Простые реализации на основе композиции ...................... 256
22.2.2. Получение идентификаторов процессов ............................ 257
22.2.3. Работа без поддержки исключений .................................... 258
22.3. Класс winstl::process_module_sequence ..................................... 259
22.4. Перебор всех модулей в системе .............................................. 260
22.5. Исключение системных псевдопроцессов ................................. 261
22.6. Когда заголовочные файлы API отсутствуют .............................. 263
22.7. Резюме ...................................................................................... 264
Глава 23. Числа Фибоначчи ....................................................... 265
23.1. Введение ................................................................................... 265
12. 1212121212 СодержаниеСодержаниеСодержаниеСодержаниеСодержание
23.2. Последовательность чисел Фибоначчи ...................................... 265
23.3. Последовательность чисел Фибоначчи как
STL последовательность ................................................................... 266
23.3.1. Интерфейс бесконечной последовательности ................... 268
23.3.2. Заключим контракт ............................................................ 269
23.3.3. А не изменить ли тип значения? ......................................... 269
23.3.4. Ограничивающий тип ......................................................... 270
23.3.5. Возбуждать ли исключение std::overflow_error? .................. 270
23.4. Трудности понимания ................................................................ 271
23.5. Определение конечных границ .................................................. 272
23.5.1. Так все таки итераторы? .................................................... 272
23.5.2. Диапазон, ограниченный конструктором ........................... 273
23.5.3. Истинные typedef’ы ............................................................ 276
23.6. Резюме ...................................................................................... 279
Глава 24. Адаптация семейства MFC контейнеров
CArray .................................................................................................. 280
24.1. Введение ................................................................................... 280
24.2. Мотивация ................................................................................. 280
24.3. Эмуляция std::vector .................................................................. 283
24.4. Размышления над проектом ...................................................... 284
24.4.1. Семейство контейнеров массивов в MFC .......................... 285
24.4.2. Класс CArray_traits .............................................................. 286
24.4.3. Проектирование адаптеров массивов ................................ 287
24.4.4. Абстрактное манипулирование состоянием ....................... 288
24.4.5. Идиома копирования с обменом ........................................ 288
24.4.6. Композиция интерфейса набора ........................................ 290
24.4.7. Педагогический подход...................................................... 290
24.5. Интерфейс класса mfcstl::CArray_adaptor_base ......................... 291
24.6. Класс mfcstl::CArray_cadaptor .................................................... 292
24.6.1. Объявление шаблона и наследование ................................ 293
24.6.2. Применение паттерна CRTP ............................................... 294
24.6.3. Конструирование ............................................................... 295
24.6.4. operator []() ........................................................................ 297
24.7. Класс mfcstl::CArray_iadaptor ..................................................... 297
24.8. Конструирование....................................................................... 298
24.9. Распределитель памяти............................................................. 299
24.10. Методы доступа к элементам .................................................. 299
24.11. Итерация ................................................................................. 300
24.11.1. Методы begin() и end()...................................................... 300
24.11.2. Методы rbegin() and rend()................................................ 301
24.12. Размер..................................................................................... 301
24.12.1. Оптимизация выделения памяти ...................................... 303
24.13. Емкость.................................................................................... 305
13. 1313131313СодержаниеСодержаниеСодержаниеСодержаниеСодержание
24.14. Сравнение ............................................................................... 307
24.15. Модификаторы ........................................................................ 310
24.15.1. Метод push_back()............................................................ 310
24.15.2. Метод assign() .................................................................. 311
24.15.3. Методы pop_back() и clear().............................................. 312
24.15.4. Метод erase() ................................................................... 313
24.15.5. Метод insert() ................................................................... 314
24.16. Присваивание и метод swap() .................................................. 316
24.16.1. Метод swap() .................................................................... 316
24.17. Резюме .................................................................................... 318
24.18. На компакт диске .................................................................... 319
Глава 25. Карта окружающей местности.............................. 320
25.1. Введение ................................................................................... 320
25.2. Мотивация ................................................................................. 320
25.3. getenv(), putenv(), setenv()/unsetenv() и environ .......................... 321
25.4. Класс platformstl::environment_variable_traits.............................. 322
25.5. Планирование интерфейса ........................................................ 325
25.6. Поиск по имени.......................................................................... 325
25.6.1. Вариант 1: возврат фиксированной/недолговечной
ссылки на кэшированный объект с актуальным значением.............. 327
25.6.2. Вариант 2: возврат фиксированной ссылки
на кэшированный объект, содержащий значение
на момент снимка .......................................................................... 328
25.6.3. Вариант 3: возврат фиксированной ссылки
на кэшированный объект с актуальным значением ........................ 329
25.6.4. Вариант 4: возврат временной по значению
ссылки на актуальное значение ..................................................... 330
25.6.5. Еще раз о поиске по имени ................................................ 331
25.7. Вставка, изменение и удаление значений по имени .................. 331
25.8. Итерация ................................................................................... 332
25.8.1. Версия 1: непрерывный итератор ...................................... 332
25.8.2. Версия 2: двунаправленный итератор ................................ 333
25.8.3. Версия 3: мгновенный снимок ............................................ 336
25.8.4. Версия 4: снимок с подсчетом ссылок................................ 338
25.9. Окончательная реализация итерации ........................................ 340
25.9.1. Изменяемый снимок?......................................................... 341
25.9.2. Создание снимка ............................................................... 342
25.9.3. Вложенный класс const_iterator .......................................... 343
25.9.4. Метод insert() ..................................................................... 344
25.9.5. Метод erase() ..................................................................... 346
25.9.6. Методы operator []() и lookup() ........................................... 348
25.9.7. Вложенный класс snapshot ................................................. 349
25.10. Гетерогенные категории ссылок? ............................................ 350
14. 1414141414 СодержаниеСодержаниеСодержаниеСодержаниеСодержание
25.11. Метод size() и индексирование числом .................................... 351
25.12. Резюме .................................................................................... 351
25.13. На компакт диске .................................................................... 352
Глава 26. Путешествие по Z плоскости – туда
и обратно ........................................................................................... 353
26.1. Пролог ....................................................................................... 353
26.2. Введение ................................................................................... 353
26.3. Версия 1: однонаправленная итерация ..................................... 356
26.3.1. Класс zorder_iterator, версия 1 ............................................ 356
26.3.2. Класс window_peer_sequence, версия 1.............................. 357
26.4. Версия 2: двунаправленная итерация ........................................ 358
26.5. Учет внешних изменений ........................................................... 360
26.5.1. Класс stlsoft::external_iterator_invalidation ........................... 361
26.6. Класс winstl::child_window_sequence .......................................... 362
26.7. Блюз, посвященный двунаправленным итераторам .................. 363
26.7.1. О стражах end() .................................................................. 363
26.7.2. Убийственное двойное разыменование ............................. 364
26.7.3. Когда двунаправленный итератор не является
однонаправленным, но оказывается обратимым и клонируемым .. 367
26.8. winstl::zorder_iterator: итератор, обратный самому себе ............ 368
26.8.1. Характеристический класс для zorder_iterator .................... 369
26.8.2. Шаблон zorder_iterator_tmpl<> ........................................... 371
26.8.3. Семантика обратной итерации ........................................... 374
26.9. Завершающие штрихи в реализации последовательностей
равноправных окон ............................................................................ 375
26.10. Резюме .................................................................................... 376
26.11. Еще о Z плоскости ................................................................... 376
Глава 27. Разбиение строки....................................................... 378
27.1. Введение ................................................................................... 378
27.2. Функция strtok() ......................................................................... 379
27.3. Класс SynesisSTL::StringTokeniser .............................................. 381
27.4. Случаи, когда применяется разбиение строки ........................... 383
27.5. Альтернативные средства разбиения строк............................... 384
27.5.1. Функция strtok_r() ............................................................... 384
27.5.2. Библиотека IOStreams ........................................................ 384
27.5.3. Функция stlsoft::find_next_token() ....................................... 385
27.5.4. Класс boost::tokenizer......................................................... 385
27.6. Класс stlsoft::string_tokeniser ..................................................... 385
27.6.1. Класс stlsoft::string_tokeniser::const_iterator ....................... 388
27.6.2. Выбор категории ................................................................ 390
27.6.3. Класс stlsoft::string_tokeniser_type_traits ............................. 391
15. 1515151515СодержаниеСодержаниеСодержаниеСодержаниеСодержание
27.6.4. Класс stlsoft::string_tokeniser_comparator ........................... 392
27.7. Тестирование ............................................................................ 394
27.7.1. Одиночный символ разделитель........................................ 394
27.7.2. Разделитель строка ........................................................... 395
27.7.3. Сохранение пустых лексем................................................. 396
27.7.4. Копировать или сослаться: поговорим о представлениях .. 396
27.8. Немного о политиках ................................................................. 399
27.8.1. Переработка параметров шаблона с помощью
наследования ................................................................................ 400
27.8.2. Шаблоны генераторы типов .............................................. 401
27.8.3. Как быть с гипотезой Хенни? .............................................. 402
27.9. Производительность ................................................................. 402
27.10. Резюме .................................................................................... 405
Глава 28. Адаптация энумераторов COM ............................. 406
28.1. Введение ................................................................................... 406
28.2. Мотивация ................................................................................. 406
28.2.1. Длинная версия .................................................................. 407
28.2.2. Короткая версия................................................................. 408
28.3. Энумераторы COM .................................................................... 409
28.3.1. Метод IEnumXXXX::Next() .................................................... 409
28.3.2. Метод IEnumXXXX::Skip() .................................................... 409
28.3.3. Метод IEnumXXXX::Reset() .................................................. 409
28.3.4. Метод IEnumXXXX::Clone() .................................................. 410
28.3.5. Различные типы значений .................................................. 410
28.4. Анализ длинной версии ............................................................. 411
28.5. Класс comstl::enumerator_sequence ........................................... 412
28.5.1. Открытый интерфейс ......................................................... 413
28.5.2. Типы и константы члены .................................................... 414
28.5.3. Политики значений............................................................. 414
28.5.4. Переменные члены ............................................................ 417
28.5.5. Конструирование ............................................................... 417
28.5.6. Методы итерации ............................................................... 419
28.5.7. Методы итератора и корректность относительно const...... 420
28.5.8. Нарушена семантика значения? ......................................... 421
28.6. Класс comstl::enumerator_sequence::iterator .............................. 421
28.6.1. Конструирование ............................................................... 423
28.6.2. Методы итерации ............................................................... 424
28.6.3. Метод equal() ..................................................................... 424
28.7. Класс comstl::enumerator_sequence:: iterator:: enumeration_
context................................................................................................ 426
28.7.1. Зачем нужен контекст обхода? ........................................... 426
28.7.2. Определение класса .......................................................... 427
28.7.3. Конструирование ............................................................... 428
16. 1616161616 СодержаниеСодержаниеСодержаниеСодержаниеСодержание
28.7.4. Вспомогательные методы для поддержки итераторов ....... 432
28.7.5. Инвариант .......................................................................... 433
28.8. Политики клонирования итераторов .......................................... 434
28.8.1. Класс comstl::input_cloning_policy....................................... 435
28.8.2. Класс comstl::forward_cloning_policy ................................... 437
28.8.3. Класс comstl::cloneable_cloning_policy................................ 438
28.9. Выбор политики клонирования по умолчанию:
применение принципа наименьшего удивления................................. 438
28.9.1. Метод empty() .................................................................... 443
28.10. Резюме .................................................................................... 443
28.10.1. Почему по умолчанию не указывать
однонаправленные итераторы? ..................................................... 444
28.10.2. Почему по умолчанию не указывать итераторы ввода? .... 444
28.10.3. Почему не ограничиться порциями размером 1? ............. 444
28.10.4. Почему не воспользоваться стандартным контейнером?... 445
28.11. Следующий шаг ....................................................................... 445
Глава 29. Интерлюдия: исправление мелких
упущений, касающихся выведения типа члена ................ 446
Глава 30. Адаптация наборов COM ......................................... 448
30.1. Введение ................................................................................... 448
30.2. Мотивация ................................................................................. 448
30.2.1. Длинная версия .................................................................. 448
30.2.2. Короткая версия................................................................. 451
30.3. Класс comstl::collection_sequence .............................................. 451
30.3.1. Открытый интерфейс ......................................................... 452
30.3.2. Типы и константы члены .................................................... 453
30.3.3. Конструирование ............................................................... 453
30.3.4. Итерация: чистое применение грязного трюка................... 454
30.3.5. Замечание по поводу метода size() .................................... 456
30.4. Политики получения энумератора ............................................. 457
30.5. Резюме ...................................................................................... 460
Глава 31. Ввод/вывод с разнесением и сбором ................ 461
31.1. Введение ................................................................................... 461
31.2. Ввод/вывод с разнесением и сбором ........................................ 461
31.3. API ввода/вывода с разнесением и сбором ............................... 463
31.3.1. Линеаризация с помощью COM потоков............................ 463
31.3.2. Класс platformstl::scatter_slice_sequence –
рекламный трейлер ....................................................................... 465
31.4. Адаптация класса ACE_Message_Queue ..................................... 468
31.4.1. Класс acestl::message_queue_sequence, версия 1 .............. 469
17. 1717171717СодержаниеСодержаниеСодержаниеСодержаниеСодержание
31.4.2. Класс acestl::message_queue_sequence::iterator................. 470
31.5. О том, как садиться на ежа ........................................................ 473
31.5.1. Кэп, эта посудина не может идти быстрее!......................... 474
31.5.2. Класс acestl::message_queue_sequence, версия 2 .............. 475
31.5.3. Специализация стандартной библиотеки ........................... 477
31.5.4. Производительность .......................................................... 479
31.6. Резюме ...................................................................................... 480
Глава 32. Изменение типа возвращаемого значения
в зависимости от аргументов.................................................... 481
32.1. Введение ................................................................................... 481
32.2. Одолжим рубин у Ruby ............................................................... 481
32.3. Двойственная семантика индексирования на C++ ..................... 483
32.4. Достижение обобщенной совместимости с помощью
прокладок строкового доступа........................................................... 484
32.5. Как распознать целочисленность? ............................................. 485
32.6. Выбор типа возвращаемого значения и перегрузки .................. 486
32.6.1. Запрет индексов в виде целого со знаком.......................... 487
32.7. Резюме ...................................................................................... 487
Глава 33. Порча итератора извне ............................................ 488
33.1. Когерентность элемента и интерфейса ..................................... 488
33.2. Элементы управления Windows ListBox и ComboBox .................. 491
33.2.1. Гонка при выборке?............................................................ 492
33.2.2. Классы listbox_sequence и combobox_sequence
в библиотеке WinSTL...................................................................... 494
33.3. Перебор разделов и значений реестра ...................................... 497
33.3.1. Так в чем проблема? .......................................................... 499
33.3.2. Библиотека WinSTL Registry................................................ 502
33.3.3. Обработка порчи итератора извне ..................................... 503
33.3.4. Класс winstl::basic_reg_key_sequence ................................. 505
33.4. Резюме ...................................................................................... 516
33.5. На компакт диске ...................................................................... 516
Часть III. Итераторы ...................................................................... 517
Глава 34.Усовершенствованный класс
ostream_iterator............................................................................... 519
34.1. Введение ................................................................................... 519
34.2. Класс std::ostream_iterator ......................................................... 520
34.2.1. Тип разности void ............................................................... 522
34.3. Класс stlsoft::ostream_iterator ..................................................... 522
18. 1818181818 СодержаниеСодержаниеСодержаниеСодержаниеСодержание
34.3.1. Прокладки, что же еще ....................................................... 524
34.3.2. Безопасная семантика ....................................................... 524
34.3.3. Совместимость с std::ostream_iterator................................ 526
34.3.4. Нарушение принципов проектирования? ........................... 526
34.4. Определение операторов вставки в поток ................................. 527
34.5. Резюме ...................................................................................... 528
Глава 35. Интерлюдия: запрет бессмысленного
синтаксиса итератора вывода с помощью паттерна
Dereference Proxy ........................................................................... 529
35.1. Класс stlsoft::ostream_iterator::deref_proxy ................................. 530
Глава 36. Трансформирующий итератор ............................. 532
36.1. Введение ................................................................................... 532
36.2. Мотивация ................................................................................. 533
36.2.1. Использование std::transform() .......................................... 534
36.2.2. Использование трансформирующего итератора ............... 535
36.3. Определение адаптеров итераторов ......................................... 537
36.3.1. Порождающие функции ..................................................... 537
36.3.2. Тип значения ...................................................................... 538
36.4. Класс stlsoft::transform_iterator .................................................. 538
36.4.1. Версия 1 ............................................................................. 538
36.4.2. Конструирование ............................................................... 540
36.4.3. Операторы инкремента и декремента
и арифметические операции над указателями .............................. 541
36.4.4. Сравнение и арифметические операции ............................ 541
36.4.5. А проблема в том, что . . . ................................................... 542
36.4.6. Версия 2 ............................................................................. 542
36.4.7. Класс stlsoft::transform_iterator ........................................... 545
36.5. Составные трансформации ....................................................... 547
36.6. Нет ли здесь нарушения принципа DRY SPOT? ........................... 548
36.6.1. Использование typedef и не временных
объектов функций ......................................................................... 548
36.6.2. Использование гетерогенных итераторов и алгоритмов .... 550
36.6.3. Носите, но аккуратно.......................................................... 551
36.7. Щепотка последовательностей помогает излечить…? .............. 552
36.8. Резюме ...................................................................................... 552
36.9. На компакт диске ...................................................................... 553
Глава 37. Интерлюдия: береженого бог бережет,
или О выборе имен . . . ................................................................. 554
Глава 38. Итератор селекции членов ..................................... 557
19. 1919191919СодержаниеСодержаниеСодержаниеСодержаниеСодержание
38.1. Введение ................................................................................... 557
38.2. Мотивация ................................................................................. 557
38.2.1. Алгоритм std::accumulate() ................................................. 558
38.3. Класс stlsoft::member_selector_iterator ....................................... 560
38.4. Беды порождающей функции .................................................... 562
38.4.1. Неизменяющий доступ к не константному массиву .............. 563
38.4.2. Неизменяющий доступ к константному массиву ................ 563
38.4.3. Изменяющий доступ к не константному массиву ............... 564
38.4.4. Неизменяющий доступ к не константному набору
с итераторами типа класса ............................................................ 564
38.4.5. Неизменяющий доступ к константному набору
с итераторами типа класса ............................................................ 565
38.4.6. Изменяющий доступ к набору с итераторами типа класса . 567
38.4.7. Выбор константных членов................................................. 567
38.5. Резюме ...................................................................................... 568
38.6. На компакт диске ...................................................................... 568
Глава 39. Конкатенация С строк .............................................. 569
39.1. Мотивация ................................................................................. 569
39.2. Негибкая версия ........................................................................ 570
39.3. Класс stlsoft::cstring_concatenator_iterator ................................. 572
39.4. Порождающие функции ............................................................. 574
39.5. Резюме ...................................................................................... 575
39.6. На компакт диске ...................................................................... 576
Глава 40. Конкатенация строковых объектов ..................... 577
40.1. Введение ................................................................................... 577
40.2. Класс stlsoft::string_concatenator_iterator ................................... 577
40.3. Гетерогенные строковые типы................................................... 580
40.4. Однако . . . ................................................................................. 580
40.4.1. Возможность присваивания ............................................... 580
40.4.2. Висячие ссылки .................................................................. 581
40.4.3. Решение ............................................................................. 581
40.5. Резюме ...................................................................................... 582
Глава 41. Характеристики адаптированных
итераторов ........................................................................................ 583
41.1. Введение ................................................................................... 583
41.2. Класс stlsoft::adapted_iterator_traits ........................................... 583
41.2.1. iterator_category ................................................................. 586
41.2.2. value_type ........................................................................... 586
41.2.3. difference_type .................................................................... 586
41.2.4. pointer ................................................................................ 587
20. 2020202020 СодержаниеСодержаниеСодержаниеСодержаниеСодержание
41.2.5. reference............................................................................. 587
41.2.6. const_pointer и const_reference ........................................... 588
41.2.7 effective_reference и effective_const_reference...................... 589
41.2.8. effective_pointer и effective_const_pointer ............................ 589
41.2.9. Использование характеристического класса ..................... 590
41.3. Резюме ...................................................................................... 590
41.4. На компакт диске ...................................................................... 591
Глава 42. Фильтрующая итерация .......................................... 592
42.1. Введение ................................................................................... 592
42.2. Неправильная версия ................................................................ 592
42.3. Итераторы члены определяют диапазон ................................... 593
42.4. Ну и что будем делать. . . ? ......................................................... 594
42.5. Класс stlsoft::filter_iterator .......................................................... 595
42.5.1. Семантика однонаправленных итераторов ........................ 595
42.5.2. Семантика двунаправленных итераторов ........................... 597
42.5.3. Семантика итераторов с произвольным доступом ............. 598
42.6. Ограничение категории итераторов .......................................... 599
42.7. Резюме ...................................................................................... 600
42.8. На компакт диске ...................................................................... 600
Глава 43. Составные адаптеры итераторов ........................ 601
43.1. Введение ................................................................................... 601
43.2. Трансформация фильтрующего итератора................................ 601
43.2.1. Порождающая функция ...................................................... 602
43.3. Фильтрация трансформирующего итератора ............................ 603
43.4. И нашим, и вашим ..................................................................... 604
43.5. Резюме ...................................................................................... 604
Эпилог................................................................................................. 605
Библиография .......................................................................... 606
21. Посвящается
Дяде Джону, который не шутил, говоря об опасностях второго раза,
Бену и Гарри, чьи просьбы «Папа, поиграй со мной»
не раз освобождали меня от целого дня тяжелой работой
(а заодно дважды не позволили уложиться в сроки),
но прежде всего
моей красавице жене Саре, без которой я мало чего смог бы добиться,
да и добиваться не стоило бы. Ее поддержка в самых разных отношениях
превосходит даже самые оптимистические мои ожидания.
22. Предисловие
Мой дядя Джон – «настоящий мачо». Крепкий, с грубыми чертами лицами, рез
кий в общении, ковбойского вида, он тем не менее признает право на страх. Поэто
му, когда он как то упомянул, что сложность второго прыжка с парашютом состо
ит в том, чтобы преодолеть страх перед уже известным, я взял это на заметку.
Теперь, написав две книги, я полностью подтверждаю его мысль. Решение при
няться за вторую, зная, сколько впереди проблем, далось мне нелегко. Так зачем
же я взвалил на себя эту ношу?
Причина подробно разъясняется в прологе и, если говорить в двух словах, сво
дится к попытке разрешить следующее, на первый взгляд, простое противоречие:
язык C++ слишком сложен;
C++ – единственный язык, достаточно мощный для моих потребностей.
Наиболее ярко это противоречие проявляется при использовании и особенно
при расширении стандартной библиотеки шаблонов (Standard Template Library –
STL). В этой книге (и в ее еще не написанном продолжении) я хотел в концентри
рованном виде представить знания и опыт, приобретенные за десять лет работы
над этой трудной и в то же время манящей темой.
Цели
В этой книге описывается один из способов использования и расширения биб
лиотеки STL. Рассматриваются следующие темы:
что такое набор и чем он отличается от контейнера;
понятие категории ссылки на элемент – почему оно важно, как определяет
ся, как распознается и какие с ним связаны компромиссы при проектирова
нии наборов и итераторов, расширяющих STL;
феномен порчи итератора извне и его влияние на проектирование совмес
тимых с STL наборов;
механизм выявления возможностей произвольных наборов, которые могут
предоставлять или не предоставлять изменяющие операции.
Даются ответы на такие вопросы:
почему трансформирующий адаптер итератора должен возвращать эле
менты по значению;
почему фильтрующему итератору всегда нужно передавать пару итера
торов;
что делать, если набор изменяется в процессе обхода;
23. 2323232323Предмет обсужденияПредмет обсужденияПредмет обсужденияПредмет обсужденияПредмет обсуждения
почему следует объявить вне закона бессмысленный синтаксис классов,
реализующих итераторы вывода, и как воспользоваться для этой цели пат
терном «Заместитель разыменования» (Dereference Proxy).
Демонстрируется, как решить следующие задачи:
адаптировать групповой API к наборам STL;
адаптировать поэлементный API к наборам STL;
обобществить состояние обхода так, чтобы удовлетворялись требования,
предъявляемые итератором ввода;
обойти потенциально бесконечный набор;
специализировать стандартные алгоритмы для конкретных типов итерато
ров с целью повышения производительности;
определить безопасное, не зависящее от платформы расширение STL для
обхода системного окружения, представленного в виде глобальной пере
менной;
адаптировать набор, копируемость итераторов которого определяется на
этапе выполнения;
предоставить неповторяемый доступ к обратимому набору;
записывать в буфер символов с помощью итератора.
В книге рассматриваются эти и многие другие вопросы. Мы также обсудим,
как можно создать универсальную совместимую со стандартом библиотеку, не
жертвуя надежностью, гибкостью и особенно производительностью. Будет рас
сказано, как безболезненно совместить абстракцию с эффективностью.
Эту книгу стоит прочитать тем, кто хочет:
изучить принципы и методы расширения библиотеки STL;
больше узнать об STL, заглянув внутрь реализации расширений;
узнать об общих способах реализации оберток вокруг API операционной
системы и библиотек, написанных для одной конкретной технологии;
узнать, как пишутся адаптеры итераторов, и разобраться в том, почему на
их реализацию и использование налагаются определенные ограничения;
познакомиться с техникой оптимизации производительности библиотек
общего назначения;
научиться применять проверенные временем компоненты для расширения
STL.
Предмет обсуждения
Я полагаю, что каждый должен писать о том, что знает. Поскольку основная
цель этой книги состоит в том, чтобы поделиться знаниями о процедуре расшире
ния STL и возникающих при этом сложностях, большая часть материала основана
на моей работе над (открытыми) библиотеками STLSoft. Тот факт, что почти все
вошедшее в эти библиотеки написано мной с нуля, позволяет мне говорить авто
24. 2424242424 ПредисловиеПредисловиеПредисловиеПредисловиеПредисловие
ритетно. Это особенно важно при обсуждении ошибок проектирования; если бы я
стал публично описывать чужие ошибки, вряд ли заслужил бы похвалу.
Но это не означает, что всякий, кто прочтет эту книгу, обязательно свяжет
себя только с STLSoft или что поклонники других библиотек не узнают из нее
ничего полезного для себя. Я собирался не воспевать какую то конкретную биб
лиотеку, а рассказать о внутренних механизмах расширения STL, обращая особое
внимание на общие принципы и методы, которые не зависят от интимного зна
комства с STLSoft или с какой либо другой библиотекой. Если, прочитав эту кни
гу, вы не станете пользоваться библиотекой STLSoft, я не обижусь. Главное, что
бы вы унесли с собой знания о том, как реализовывать и применять другие
расширения STL.
Я вовсе не утверждаю, что описанный мной метод расширения STL – един
ственно возможный. C++ – очень мощный язык, который поддерживает самые
разные стили и технику, иногда даже во вред самому себе. Например, многие, хотя
и не все, наборы лучше реализовывать в виде STL наборов, но есть и такие, для
которых больше подходят автономные итераторы. Здесь существует значитель
ное перекрытие и неопределенность.
При обсуждении большинства расширений STL читатель (а иногда и автор!)
начинает с обертывания исходного API в промежуточные, часто дефектные, клас
сы и лишь постепенно приходит к оптимальной или, по крайней мере, близкой
к оптимальной реализации. Я не ухожу от сложностей, неважно, касаются они реа
лизации или концепции. Сразу хочу сказать, что некоторые приемы преобразова
ния внешнего API в форму STL требуют незаурядной технической изобретательно
сти. Я не стану ради простоты изложения притворяться, что никаких сложностей
не существует, и пропускать их объяснение при описании реализации. Все будет
рассмотрено подробно, и тем самым я надеюсь достичь двух целей: (1) показать,
что все не так уж сложно, и (2) объяснить, почему сложность все таки необходима.
Один из лучших способов понять STL состоит в том, чтобы разобраться, как
реализованы компоненты STL, а для этого лучше всего реализовать их самостоя
тельно. Если у вас на это нет времени (или желания), то я рекомендую следующий
по эффективности способ – прочитать эту книгу.
Организация книги
Эта книга состоит из трех основных частей.
Часть I: Основы
Это собрание небольших глав, закладывающих фундамент для частей II и III.
Мы начнем с краткого описания основных особенностей библиотеки STL, а затем
обсудим идеи и принципы расширения STL, в том числе и новое понятие катего
рии ссылок на элементы. В следующих главах рассматриваются базовые понятия,
механизмы, парадигмы и принципы: совместимость, ограничения, контракты,
принцип DRY SPOT, идиома RAII и прокладки (shims). И напоследок мы погово
рим о технике применения шаблонов, в том числе характеристических классах
25. 2525252525
(traits) и выводимой адаптации интерфейса, а также о нескольких важных компо
нентах, которые найдут применение в реализациях, описываемых в части II и III.
Часть II: Наборы
Это основная часть книги. В каждой главе рассматривается один или несколь
ко реальных наборов и их приведение к стандарту STL, включая и соответствую
щие типы итераторов. Речь пойдет о таких разнородных материях, как обход фай
ловой системы, энумераторы COM, контейнеры, не входящие в состав STL, ввод/
вывод с разнесением и сбором, и даже наборы, элементы которых могут изменять
ся извне. Мы поговорим о выборе категории итератора и о категориях ссылок на
элементы, об обобществлении состояния и о порче итераторов извне.
Часть III: Итераторы
Если в части II речь идет об определении типа итератора, ассоциированного
с набором, то часть III целиком посвящена автономным итераторам. Здесь рассмат
риваются различные вопросы, как то: специализированные типы итераторов, в том
числе простое расширение функциональности класса std::ostream_iterator;
изощренные адаптеры итераторов, которые могут фильтровать и трансформиро
вать типы или значения в тех диапазонах, к которым применяются, и т.д.
Том 2
Второй том еще не закончен и его структура окончательно не определена, но
речь пойдет о функциях, алгоритмах, адаптерах, распределителях памяти и по
нятиях диапазона и вида, расширяющих инструментарий STL.
Дополнительные материалы
CD ROM
На прилагаемом компакт диске находятся различные бесплатные библиотеки
(включая все рассматриваемые в тексте), тестовые программы, инструменты и
другое полезное программное обеспечение. Включен также полный, хотя и не
отредактированный, текст трех глав, не вошедших в окончательный вариант (что
бы сэкономить место и избежать чрезмерной зависимости от компилятора), и
многочисленные примечания и подразделы из других глав.
Онлайновые ресурсы
Дополнительные материалы можно найти также на сайте http://extendedstl.com/.
Дополнительные материалыДополнительные материалыДополнительные материалыДополнительные материалыДополнительные материалы
26. Благодарности
Разумеется, я очень многим обязан своей жене Саре. Во время работы над этой
книгой, равно как и над предыдущей, она неизменно поддерживала меня и почти
не жаловалась, несмотря на раз за разом переносимые сроки. Она надеется, что
это моя последняя книга. Но поскольку брак – это искусство компромисса, то я
пообещал ей, что на следующую книгу я потрачу годы (а не месяцы). Пожелайте
мне удачи.
Еще хочу поблагодарить свою маму и Роберта за решительную поддержку и,
в особенности за терпение, с которым они относились к моим вопросам по грамма
тике в любое время дня и ночи (они живут в часовом поясе GMT, а я в GMT+10).
Работая над книгой, я намотал на велосипеде тысячи километров, частенько
с моим (более молодым и крепким) другом Дейвом Трейси. В те дни, когда я не
останавливался через каждые несколько километров, чтобы записать очередную
порцию вдохновений, я катался с Дейвом, который отвлекал меня от неотвязных
мыслей об STL и всячески ободрял. Спасибо, Дейв, но помни – Доктор тебя еще
когда нибудь обгонит!
Гэрт Ланкастер выступал в самых разных ролях: советчика, клиента, друга,
сотрапезника, рецензента. Гэрт, спасибо за частые, но всегда полезные, вмеша
тельства в мои программы, книги, дела и меню. Встретимся на обеде у Нино!
Саймон Смит – один из моих старейших друзей в стране, давшей мне приют, и
исключительно толковый парень. Я знаю, что это так, отчасти потому, что его по
стоянно стараются залучить все более крупные и известные компании, которые
по достоинству ценят его выдающиеся способности технического руководителя,
а отчасти потому, что он поручает мне анализировать свои обязанности, чтобы по
нять, как еще эффективнее применить свои уникальные таланты (а, может, он
просто добр ко мне).
Процесс написания книги часто происходил под громкую музыку, поэтому я
должен поблагодарить своих любимых фанк музыкантов: группу 808 State, Барри
Уайта, Level 42, MOS, New Order, Стиви Уондера и – разумеется, как же без него, –
Fatboy Slim. Вперед, Норман, давай еще одну! И особенно хочется сказать спасибо
двум артистам, чья чудесная музыка сопровождала меня на всем пути от востор
женного юноши к полному энтузиазма дяде, мужу и отцу. Во первых, Джорджу
Майклу за его фанк бит и за доказательство того, что быстро только кошки родятся
(в чем я и пытался убедить своего редактора на протяжении 18 месяцев со дня ис
течения первого срока сдачи рукописи). И, хотя я и принадлежу к тем самым маль
чикам (сдавшим все экзамены на отлично; правда, в банке Джодрелл никогда не
27. 2727272727
работал), благодарю Падди МакАлуна (Paddy MacAloon)1
, который, несомненно,
является величайшим лирическим певцом за последние три десятилетия.
Раз уж зашла речь о редакторе, то я просто обязан выразить благодарность
Питеру Гордону (Peter Gordon), который умело и непреклонно руководил мной
на протяжении всего этого марафона и уговаривал «писать поменьше слов». По
мощница Питера, Ким Бодигхеймер (Kim Boedigheimer), также заслуживает са
мых лестных слов за умение все организовать и за терпение к моим бесконечным
просьбам: то мне нужно устройство ввода, то аванс, то книжки задаром. Спасибо
также Элизабет Райан (Elizabeth Ryan), Джону Фуллеру (John Fuller), Мари
МакКинли (Marie McKinley) и особенно терпеливому и всепрощающему коррек
тору с ласкающим вкус и обоняние именем Криста Мэдоубрук (Chrysta Meadow
brooke).
Теперь дошла очередь и до рецензентов, которым я бесконечно обязан: Ади
Шавит (Adi Shavit), Гэрт Ланкастер (Garth Lancaster), Джордж Фразье (George
Frazier), Грег Пит (Greg Peet), Nevin : ) Liber, Пабло Агилар (Pablo Aguilar), Скотт
Мейерс (Scott Meyers), Шон Келли (Sean Kelly), Серж Крынин (Serge Krynine) и
Торстен Оттосен (Thorsten Ottosen). Никакими словами нельзя в полной мере
выразить мою благодарность, поэтому, как принято, благодарю за исправление
моих ошибок и принимаю на себя всю ответственность, если я где то упрямо оста
вался при своем, возможно неверном, мнении.
Хочу также поблагодарить ряд людей, повлиявших на эту книгу иными спосо
бами: Бьярна Страуструпа, Бьерна Карлсона (Bjorn Karlsson), Гэрта Ланкастера,
Грега Комея (Greg Comeau), Кевлина Хэнни (Kevlin Henney) и Скотта Мейерса.
Ценным советом или добрым словом они, пусть тонко и неощутимо, но оказали
огромное влияние на окончательный вариант этой книги (и тома 2). Большое спа
сибо.
И наконец спасибо пользователям библиотек Pantheios и STLSoft, многие из
которых предлагали помощь, высказывали критические замечания технического
характера, вносили предложения и даже требовали предоставить им допечатный
вариант рукописи! Надеюсь, что результат вас не разочарует.
Еще о парашютах
Кстати, дядя Джон говорит, что прыгать с парашютом в третий раз уже не
страшно. Учту при подготовке следующих двух книг, к которым собираюсь при
ступить, как только отошлю эту в издательство. До встречи через год!
1
Цитата из песни «Technique» группы Prefab Sprout (it’s for men with horn rimmed glasses,
and four distinguished «A Level» passes) (Прим. перев.)
БлагодарностиБлагодарностиБлагодарностиБлагодарностиБлагодарности
28. Об авторе
Мэтью Уилсон – консультант, работающий по контракту с компанией Synesis
Software, разработчик библиотек STLSoft и Pantheios. Автор книги Imperfect C++
(Addison Wesley, 2004), вел колонку в журнале C/C++ Users Journal и пишет ста
тьи для нескольких ведущих периодических изданий. В настоящее время прожи
вает в Австралии, степень доктора философии получил в Манчестерском государ
ственном университете в Великобритании.