>>Постинкремент итераторов всё же стоит заменить на преинкремент. Коротко. оказывается даже на васме чему-то еще можно научиться! Спасибо за этот финт cupuyc Код (Text): typename t_string = std::basic_string<t_base_charset>, typename t_states = std::vector<t_parse_state>, typename t_transfers = std::vector<t_states> А нельзя ли подобное в какой-нить traits ? Подобные имена "basic_parser" как-то уже не по плюсовому! Лучше BasicParser. ИмХО Зачем нужен "base_exception", когда вполне хватает std::runtime_error ? Код (Text): class basic_parser { protected: ... x_transfers m_transfers; Нафига такое делать? Это все равно что открыть приватные данные клиентоскому коду!!! Для потомков надо тоже закрывать, предоставляя им методы доступа,так достигается большая инкапсуляция! По сути потомок становится клиентом базового класса ЗЫ: мои коменты на основанаии сорцов в первом посте
>>GoldFinch, что вы считаете написано плохо? Ты видешь "написано хреново" ? Я нет, думаю и ты тоже не видешь, значит не считает, если бы считал написал бы explicit! То есть явно То что юзается STL даже для такой мелкой задачи не так страшно, чем написать туеву хучу кода на чистом си на какую-то учебную задачу.
cupuyc всё не перечислить # base_exception - чтоэта? почему "base_", а используется как конкретный класс? what() обязано возвращать m_message.c_str() и не в коем случае не 0. потому что часто используют что-то вроде Код (Text): int main() try { ....... } catch(std::exception& e) { std::cerr << e.what() << std::endl; } чтобы поймать любые exception'ы и показать их сообщения. именно по этому what виртуальная, а ваш message() никому не нужен # typedef unsigned int uint_t; Это чтобы меньше букв писать? или вы собираетесь потом сделать uint_t не unsigned int а чем-то еще? отдельный заголовочный файл для такого - это перебор # explicit basic_parser() тут explicit не нужен # typedef std::map<std::wstring, std::wstring> variables_list; # enum expr_char_type { ctAny = 0, ctLetter, ...} всё это будет торчать в global namespace, причем это в заголовочном файле это должно быть в expr_parser, либо в какомнить namespace detail # variables_list* m_variables; зачем делать указатель на map? у него семантика значения, как и у остальных контейнеров а где тогда проверка на NULL ? ссылку там надо. код конструктора это вообще жесть %) если я добавлю в enum'ы пару новых элементов, мне сколько комбинаций надо перебирать? там надо применить метапрограммирование, хотя бы c BOOST_PP Код (Text): if (ch >= L'a' && ch <= L'z') return ctLetter; велосипед =\ если хочется своё - проверяйте тогда уж по таблице, это эффективнее и мне непонятно, там вот этот здоровый шаблон с кучей параметров, он зачем? только для метода basic_parser::process_parse? get_char_type например надо переписывать по-новой для других типов
Да, согласен. Я почему-то думал, что у std::exception метод what() пустой. Ошибался. Ну, не знаю. Много проектов видел в которых юзаются такие типы, как uint_t, uint32_t, и т.п. Удобнее, нежели каждый раз писать unsigned int. Мало того, в MSVC хидера stdint.h нет вообще, а в Code::Blocks, например, есть. Чтобы как-то стандартизировать я создаю свой хидер, где определяю соответствующие типы (если это MSVC) или просто подключаю stdint.h (если это gcc). // в данном случае типы uint32_t int16_t и пр. не были нужны - поэтому не стал описывать. Понятно, что хидер не для одного типа. Странно.. http://insidecpp.ru/notes/5/ Ок. Ок. Так ведь всё-равно придётся описывать все переходы автомата.. Как быть? Из статьи Дело в том, что я не хочу привязываться к бусту. Табличку, думаю, написать можно. GoldFinch, спасибо за критику. Учту!