LINUX.ORG.RU

Адекватная замена элипсисам (...) в C++


0

0

Есть ли какая-нибудь адекватная замена элипсисам в C++?
Элипсисы конечно очень удобны, однако они небезопасны и к тому же 
применение средств C в программах на C++ должно быть по возможности
минимальным (моё мнение).

Мне нужно для следующей задачи:
Написал класс LoggerChain - цепочка логгеров (syslog, файл, stderr 
и т.п.).
Класс содержит в себе следующий объект:
std::vector<boost::shared_ptr<BaseLoggerDevice> >

У класса BaseLoggerDevice естественно есть виртуальная функция 
для вывода в лог.
В векторе хранятся интелектуальные указатели на потомков базового
класса.

Метод WriteToLog класса LoggerChain просто перебирает вектор и 
для каждого устройства вызывает функцию вывода.

Сам класс LoggerChain у меня будет синглтоном (что логично)
и чтобы не замарачиваться на постоянные обращения к Instance()
я хочу описать макрос-враппер logg.

Прототип logg естественно следующий:
logg(const char* fmt,...)

Короче проблема понятна.
Есть у кого-нибудь идеи?

Однако, полиморфик параметром...

Какой-то даже паттерн на эту тему есть, не помню наизусть.

Die-Hard ★★★★★
()
Ответ на: комментарий от Die-Hard

>Какой-то даже паттерн на эту тему есть, не помню наизусть.
Ну это я сейчас посмотрю - у меня 3 книги по паттернам!

Krivenok_Dmitry
() автор топика

зачем в данной задаче ellipsis не очень понятно.

но навскидку решение, если не хочется ellipsis.

делаем сколько нужно что-то вроде

std::stringstream& operator<<(std::stringstream& s, myclass const& obj) { something. }

и в этом logger chain что-то вроде

template<class T> LoggerChain& operator<<(T const& obj) {
  internal_stringstream_ << obj;
}

только вот на мой вкус - должен быть класс logger, а что там внтури, chain или еще какая штука - неважно.

AnToXa
()

> Сам класс LoggerChain у меня будет синглтоном (что логично) и чтобы не замарачиваться на постоянные обращения к Instance() я хочу описать макрос-враппер logg.

Гм... а просто объявить одну глобальную переменную 'log' данного класса, и перегрузить для него operator<<, не судьба? Как это в iostream сделано.

int19h ★★★★
()
Ответ на: комментарий от int19h

>Гм... а просто объявить одну глобальную переменную 'log' данного класса, и перегрузить для него operator<<, не судьба? Как это в iostream сделано.

Помоему именно для лога удобнее писать
logg("Error[%d] : %s \n",ERR_CODE,ERR_MSG);
а не
logg << "Error[" << ERR_CODE << "] : " << ERR_MSG << " \n";  

Не находишь, что короче и проще!
Т.к. многие сообщения будут только в debug mode и их будет 
много, хочется максимально сократить запись!

Своим вариантом ты навёл меня на другое решение с использованием
boost::format.
Попробую реализовать.

Спасибо!

Krivenok_Dmitry
() автор топика
Ответ на: комментарий от Krivenok_Dmitry

> Помоему именно для лога удобнее писать
logg("Error[%d] : %s \n",ERR_CODE,ERR_MSG);
а не
logg << "Error[" << ERR_CODE << "] : " << ERR_MSG << " \n";
> Не находишь, что короче и проще!
Т.к. многие сообщения будут только в debug mode и их будет
много, хочется максимально сократить запись!

ууу.. какой флеймовый топик пошёл.. ;)

typedef unsigned long foo_t;
foo_t f;
logg("%ul", f);

..минул год...

typedef short foo_t
foo_t f;
s/logg("%ul", f)/logg("%hd", f)/g
...и так тысячи раз в сотнях файлов..
радость, правда?
а если еще добавим пляски 32 vs 64, то получится полная прелесть.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от anonymous

anonymous (*) (27.09.2005 21:41:12):

> Надоели безтолковые плюсисты. За каждым чихом лезут в форум.

Кстати, несмотря на хамоватый тон, доля истины присутствует.

Надо почаще своей головой думать. В этом смысле полезность преподавания паттернов студентам IMHO несколько спорная вещь. По крайней мере, в нынешнем виде...

Die-Hard ★★★★★
()
Ответ на: комментарий от Krivenok_Dmitry

> Не находишь, что короче и проще!

Нахожу, но "короче и проще" - это не на плюсах вообще надо писать =)

> Своим вариантом ты навёл меня на другое решение с использованием boost::format.

Ага, как раз хотел про это напомнить. Вообще пихать форматирование в класс, занимающийся выводом, не стоит - это не его задача. В этом смысле отдельный оператор форматирования, как % в питоне и слизанном с него boost::format, намного более правильное решение.

int19h ★★★★
()

Это что ли?

#define logg(fmt,...) LoggerChain::Instance().WriteToLog(fmt,__VA_ARGS__)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.