Комментарии 46
А почему изобретён велосипед для логгинга? Ведь есть же log4cpp.
0
Так в том то и дело, что если вы используете POCO, то вам не нужно обременять себя заботой о ведении проекта с дополнительными библиотеками. Как следствие отпадает необходимость в обновлении, перекомпилировании.
+3
Боже упаси юзать log4cpp, куда лучше boost.log или glog
+3
Legacy code :(
0
Ещё очень неплох log4cplus
0
Какие ваши критерии по выбору библиотеки логирования?
0
Я рассматривал следующие критерии:
— Конфигурации логирования без перекомпиляции приложения. Возможность переконфигурации уже запущенного приложения «на лету»
— Поддержка многопоточности
— Возможность вывода в stdout/stderr/file/debug output/console/… Возможность асинхронного логирования
— Возможность настройки формата вывода лога
— «Хорошая» лицензия
— Кроссплатформенность + поддержка VS 2010
— Библиотека не «заброшена»
— Поддержка нескольких уровней логирования
— (желательно) наличие stream-like интерфейса (как при выводе в std::ostream)
Под них хорошо подходили log4cplus, и POCO::Logging. В итоге остановились на первом (не хотелось тянуть всю библиотеку только ради логирования)
— Конфигурации логирования без перекомпиляции приложения. Возможность переконфигурации уже запущенного приложения «на лету»
— Поддержка многопоточности
— Возможность вывода в stdout/stderr/file/debug output/console/… Возможность асинхронного логирования
— Возможность настройки формата вывода лога
— «Хорошая» лицензия
— Кроссплатформенность + поддержка VS 2010
— Библиотека не «заброшена»
— Поддержка нескольких уровней логирования
— (желательно) наличие stream-like интерфейса (как при выводе в std::ostream)
Под них хорошо подходили log4cplus, и POCO::Logging. В итоге остановились на первом (не хотелось тянуть всю библиотеку только ради логирования)
+2
std::string text = config().getString("Group.ValueText"); // text == "Hello world"
int value = config().getInt("Group.IntValue"); // value == 123
Ну что за адЪ? Почему нельзя было сделать
auto text = config().value("Group.ValueText", "Some default text");
auto int = config().value("Group.IntValue", 100500);
?
0
А такая жёсткая привязка к C++0х разве не противопоказана библиотеке широкого применения?
-1
Вопрос стоит скорей, возможно ли использовать такой код в рамках стандарта C++03 и без RTTI
И насколько данный код будет производителен.
string text = config().value("Group.ValueText");
int integ = config().value("Group.IntValue");
И насколько данный код будет производителен.
0
И к тому же возможны преобразование Int -> string, но не всегда наоборот (ваш К.О.)
0
А вы не поняли кода просто
А там уж или преобразование типа Any в нужный тип делать или специализировать для int, std::string, const char * и так далее. Скорость будет точно такой же как и в случае с кучей stringValue, intValue, а объем кода заметно меньше и апи чище.
template <typename T>
T Config::value(const std::string &key, const T &defValue);
А там уж или преобразование типа Any в нужный тип делать или специализировать для int, std::string, const char * и так далее. Скорость будет точно такой же как и в случае с кучей stringValue, intValue, а объем кода заметно меньше и апи чище.
+3
Только там не Any, разработчики решили не связываться с RTTI, наверняка поэтому такая «красота».
Однако ваш метод имеет право на жизнь, можно отправить предложение разработчикам.
Однако ваш метод имеет право на жизнь, можно отправить предложение разработчикам.
0
Если возникнет необходимость различать, например, int и char, то придется писать что-то вроде
А еще когда вы пишете «stringValue», код более читабельный: сразу видно, какой тип вы ожидаете на выходе. А в вашем варианте сразу это поймет только человек, который знаком с функцией value и знает, что ее тип зависит от типа второго аргумента. По умолчанию это неочевидно.
Я не утверждаю, что ваш вариант хуже. Я считаю, в каждом из них есть плюсы и минусы. А мне больше всего нравится вариант, реализованный в Qt: функция QSettings::value возвращает объект псевдодинамического типа QVariant, который затем может быть преобразован к нужному типу с помощью toString(), toInt() и т.д. Кстати, в Poco вроде есть аналог этого типа.
value(key, (char) 1)
, это получается более громоздко, чем charValue(key)
. К тому же приведение типов может сработать очень неочевидно и привести к неожиданным последствиям, а в коде будет выглядеть вполне правдоподобно. Ярким пример тому — функция QString::arg, значение которой может разительно изменяться в зависимости от того, передали вы 'x' или QChar('x'). Поэтому рассматривать перегрузку метода как панацею не стоит. А еще когда вы пишете «stringValue», код более читабельный: сразу видно, какой тип вы ожидаете на выходе. А в вашем варианте сразу это поймет только человек, который знаком с функцией value и знает, что ее тип зависит от типа второго аргумента. По умолчанию это неочевидно.
Я не утверждаю, что ваш вариант хуже. Я считаю, в каждом из них есть плюсы и минусы. А мне больше всего нравится вариант, реализованный в Qt: функция QSettings::value возвращает объект псевдодинамического типа QVariant, который затем может быть преобразован к нужному типу с помощью toString(), toInt() и т.д. Кстати, в Poco вроде есть аналог этого типа.
+3
> auto int = config().value(«Group.IntValue», 100500);
Меня все больше и больше страшат нововведения в стандарт C++.
Что сия команда значит?
Меня все больше и больше страшат нововведения в стандарт C++.
Что сия команда значит?
-2
auto intA = config().value(«Group.IntValue», 100500);
//Все довольно таки просто:
//config().value(«Group.IntValue», 100500) - вернет int, в соотв. с типом 2ой переменной
//при инициализации intA примет тип rvalue, то есть int
//данная декларация аналогична
int intA = config().value(«Group.IntValue», 100500);
0
Как же задолбала эта КДПВ!
Что ни статья на околодевовскую тематику, так обязательно в ней этот дом на курьих ножках :)
Что ни статья на околодевовскую тематику, так обязательно в ней этот дом на курьих ножках :)
+6
Программирование на XML. Теперь и в C++.
-2
Сами эти POCO не во всем придерживаются того что придумали. Соглассно их кодинг-стайлу: строчка из poco-1.4.3p1\Net\src\NameValueCollection.cpp:
должна быть совершенно другой:
Странно. Вроде дядьки умные, а почему-то не юзают то что сами и разрабатывают!
const std::string& NameValueCollection::get(const std::string& name, const std::string& defaultValue) const
{
должна быть совершенно другой:
const std::string& NameValueCollection::get(
const std::string& name,
const std::string& defaultValue) const
{
Странно. Вроде дядьки умные, а почему-то не юзают то что сами и разрабатывают!
+1
НЛО прилетело и опубликовало эту надпись здесь
Класс! Следующее же мелкое приложение напишу с POCO, столько всяких мелких вкусностей, которые раньше руками приходилось делать или собирать: glog, TCLAP (аргумент командной строки) и прочее.
Спасибо!
Спасибо!
+1
Добро пожаловать на темную сторону.
0
Наоборот, светлая сторона просвещения. Темная сторона с++ это как раз сильная разрозненность библиотек и подходов. Стандартизация, хотя бы де-факто, базовых возможностей — это хорошо. Не нужно изобретать логгер каждый раз. Был бы стандартный — 90% разработчиков бы пользовались. Так же и со всякими приведенными в посте остальными вещами.
+2
Ну судя по описанию, это хоть и хорошая библиотека, но в значительной степени пересекается с boost, при этом уступая ей в гибкости. И boost куда ближе к «стандартной», собственно он начался с библиотеки модулей, которые не попали в страндарт, а часть модулей легли в основу C++11
0
Хотите стандартизацию дефакто, юзайте Qt или буст на крайняк, а про остальное забудьте
0
Qt я так и не трогал — мне не нравится этот дополнительный компилятор.
буст конечно использую, это же мейнстрим — что сегодня в бусте, завтра в стандарте, ну или и завтра в бусте, но все так же де факто считают его стандартом.
Ну поко миленький и довольно известный. Еще из известных слышал про ACE и ICU (для юникода, юзал, умеет все, что только можно представить, ибо это и есть реализация стандарта юникода)
буст конечно использую, это же мейнстрим — что сегодня в бусте, завтра в стандарте, ну или и завтра в бусте, но все так же де факто считают его стандартом.
Ну поко миленький и довольно известный. Еще из известных слышал про ACE и ICU (для юникода, юзал, умеет все, что только можно представить, ибо это и есть реализация стандарта юникода)
0
Я отказался от TCLAP в пользу boost.program_options и не жалею! )
0
Ну это если вы тянете буст. На тот момент я не тянул, там был небольшой проект, но с кучей опций. Зато он header-only, что сильно выделяло его на фоне всех остальных библиотек.
0
>>На тот момент я не тянул
Что вы вкладываете в эти слова? Не знание?
>>Зато он header-only
Буст солидной частью тоже в хидер-онли
Что вы вкладываете в эти слова? Не знание?
>>Зато он header-only
Буст солидной частью тоже в хидер-онли
0
Не изпользовал. Это в некотором смысле была лабараторная и была острая необходимость, чтобы проект суммарно занимал несколько мегабайт. Я знаю, что можно с помощью bcp отобрать только нужные хедеры из буста, но там такие зависимости, что даже самый незначительный shared_ptr тянет 3 мб сорцов.
>> Буст солидной частью тоже в хидер-онли
бесспорно, но про program_options я не знаю, а там бывает, что на ровном месте библиотека требует компиляции. boost filesystem, например.
>> Буст солидной частью тоже в хидер-онли
бесспорно, но про program_options я не знаю, а там бывает, что на ровном месте библиотека требует компиляции. boost filesystem, например.
0
Спасибо. Интересно. Сам недавно смотрел на POCO, но так и не решил использовать. Было бы очень интересно почитать
и особенно о
о модулях XML, ZIP, Data, Net
и особенно о
создании высокопроизводительных серверов на POCO
+1
Картинка такая жизненная…
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Portable Components, вспомогательные средства разработки ПО