В этом совете были показаны некоторые текстовые подстановки, уменьшающие сложность сообщений об ошибках, но после непродолжительной практики вы сможете выполнять подстановки в голове. Я не музыкант, но мне рассказывали, что хорошие музыканты способны читать партитуру целиком, не присматриваясь к отдельным нотам. Опытные программисты STL приобретают аналогичные навыки. Они могут автоматически преобразовать конструкцию вида std::basic_string,std::allocator > в string, нисколько не задумываясь над происходящим. Подобный навык разовьется и у вас, но до этих пор следует помнить, что диагностику компилятора почти всегда можно привести к вразумительному виду заменой длинных типов на базе шаблонов более короткими мнемоническими обозначениями. Во многих случаях для этого достаточно заменить расширенные определения типов именами, используемыми в программе. Именно это было сделано в приведенном примере, когда мы заменили std::map,class std::allocator > на NicknameMap.

Далее приведены некоторые рекомендации, которые помогут вам разобраться в сообщениях компилятора, относящихся к STL.

•Для контейнеров vector и string итераторы обычно представляют собой указатели, поэтому в случае ошибки с итератором в диагностике компилятора обычно указываются типы указателей. Например, если в исходном коде имеется ссылка на vector:: iterator, в сообщении почти наверняка будет упоминаться указатель double*. Исключение составляет реализация STLport в отладочном режиме; в этом случае итераторы vector и string не являются указателями. За информацией о STLport и отладочном режиме обращайтесь к совету 50.

•Сообщения, в которых упоминаются back_insert_iterator, front_insert_iterator и insert_iterator, почти всегда означают, что ошибка была допущена при вызове back_inserter, front_inserter или inserter соответственно (back_inserter возвращает объект типа back_insert_iterator, front_inserter возвращает объект типа front_insert_iterator, a inserter возвращает объект типа insert_iterator; за информацией об этих типах обращайтесь к совету 30). Если эти функции не вызывались в программе, значит, они были вызваны из других функций (косвенно или явно).

•Сообщения с упоминаниями binder1st и binder2nd обычно свидетельствуют об ошибке при использовании bind1st и bind2nd (bind1st возвращает объект типа binder1st, a bind2nd возвращает объект типа binder2nd).

•Итераторы вывода (например, ostream_iterator и ostream_buf_iterator — см. совет 29, а также итераторы, возвращаемые back_inserter, front_inserter и inserter) выполняют свои операции вывода или вставки внутри операторов присваивания, поэтому ошибки, относящиеся к этим типам итераторов, обычно приводят к появлению сообщений об ошибке внутри операторов присваивания, о которых вы и понятия не имеете. Чтобы понять, о чем идет речь, попробуйте откомпилировать следующий фрагмент:

vector v;// Попытка вывода содержимого

copy(v.begin(),v.end(),// контейнера указателей string*

ostream_iterator(cout."\n")); // как объектов string

•Если полученное сообщение об ошибке исходит из реализации алгоритма STL (то есть если код, в котором произошла ошибка, находится в ), вероятно, проблема связана с типами, которые вы пытаетесь передать этому алгоритму. Пример — передача итераторов неправильной категории. Попробуйте откомпилировать следующий фрагмент:

list::iterator 11,12; // Передача двусторонних итераторов

sort(11.2);// алгоритму, которому необходимы итераторы

// произвольного доступа

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

Все книги серии Библиотека программиста

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