| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > va_args,__VA_ARGS__ и enum |
| Автор: flagist0 1.11.2007, 15:14 |
| Есть функции вывода и логгирования ошибок - void error(int level, const char* msg, ...) и log.printf(const char *msg, ...). Обе принимают параметры в стиле printf - форматная строка и имена параметров. Еще есть переменные int debug_lvl и log_lvl, хранящие уровни вывода (например, мы можем выводить только fatal error'ы и ничего не логгить). Уровни сообщений хранятся в enum DebugMsg{Disabled=-1,FatalError=0, Error,Warning,Message}; Нужна функция, которая будет в зависимости от текущих уровней вызывать error и log.printf. Например, void log_and_error(DebugMsg lvl,const char* msg), то есть принимаем уровень выводимого сообщения и УЖЕ скомпонованное с помощью sprintf'a сообщение;или void log_and_error(DebugMsg lvl,const char* msg, ...) - то же самое, но параметры мы должны передавать сами. Соответственно, два вопроса на выбор 1.Чтобы не делать руками перед каждым вызовом log_and_error sprintf(expanded_msg,"Watch for %s added [descriptor=%d].\n",filenames[wd],wd)), я написал мааленький макрос, который это делает сам - #define _log_and_error(lvl,...) {sprintf(expanded_msg,__VA_ARGS__);log_and_error(lvl,expanded_msg);} В нем используется __VA_ARGS__ (C99) и естественно ничего не работает. gcc (4.2.0) говорит :предупреждение: cannot pass objects of non-POD type ‘struct std::basic_string<char, std::char_traits<char>, std::allocator<char> >’ through ‘...’; call will abort at runtime и в самом деле вылетает (Недопустимая инструкция). видимо дело в перечислении. 2. В случае log_and_error(DebugMsg lvl,const char* msg, ...), как же цивилизованно передать все параметры после lvl error и log?? Насколько я понял у Страуструпа, надо знать их тип, но мне не нужен разбор, мне нужно их просто передать функциям дальше!! Заранее спасиб, извините за спам |
| Автор: JackYF 1.11.2007, 15:21 |
filenames[wd].c_str(), ws.c_str() попробуй. Вопрос в пустоту: а может, стоит отказаться от этой практики и заюзать boost::format - более прозрачное и типобезопасное решение? |
| Автор: xvr 1.11.2007, 15:30 | ||||
В данном случае можно просто отформатировать строку самому, а дальше ее передать уже в виде строки целиком, а не в виде формата и набора параметров:
Что касается передачи string в ... - то это работать будет, но не так, как ожидалось - спецификатор параметра %s в printf принимает строку с C стиле (char*), а string, да еще и переданный по значению, это совсем не то же самое |
| Автор: flagist0 1.11.2007, 16:50 | ||||||||||
Извиняюсь, криво выразился.
Вопрос в том, как не загрязнять код sprintf'ами перед каждым выводом через log_and_error. Если бы sprintf возвращал бы указатель на сформированную строку, то я бы писал
А приходится писать
Я реализовал это в виде макроса _log_and_error, но ведь наверное есть лучший вариант?
Вполне возможно. Во всяком случае boost::lambda где-то в проекте уже используется. |