С boost/program_options/value_semantic.hpp
:
/** Specifies default value, which will be used
if none is explicitly specified. The type 'T' should
provide operator<< for ostream.
*/
typed_value* default_value(const T& v)
{
m_default_value = boost::any(v);
m_default_value_as_text = boost::lexical_cast<std::string>(v);
return this;
}
/** Specifies default value, which will be used
if none is explicitly specified. Unlike the above overload,
the type 'T' need not provide operator<< for ostream,
but textual representation of default value must be provided
by the user.
*/
typed_value* default_value(const T& v, const std::string& textual)
{
m_default_value = boost::any(v);
m_default_value_as_text = textual;
return this;
}
Таким образом, реализация очень проста (никогда не бывает уверенным в Boost!). Попытка перенастроить ваш ostream, чтобы форматирование получилось так, как вы хотите, не будет работать, потому что значение по умолчанию просто преобразуется в строку в автономном ostringstream
(внутри lexical_cast
).
Итак, простой обходной путь - добавить желаемое строковое представление в качестве второго аргумента в default_value
. Затем вы можете распечатать его так, как хотите (в том числе и вовсе, если вы пропустите пустую строку). Вот так:
value(&config.my_double)->default_value(0.2, "0.2")
Более "предприимчивым" способом для достижения той же цели было бы реализовать свой собственный тип, который бы обернул double
, использовался бы для config.my_double
, и предоставил бы конструкцию и приведение к double
, и ваш собственный ostream& operator<<
с точно желаемым форматированием. Однако я не предлагаю такой подход, если только вы не пишете библиотеку, требующую универсальности.
Из Boost Lexical Cast примечания:
Предыдущая версия lexical_cast
используется точность потока по умолчанию для
чтение и запись с плавающей точкой
номера. Для чисел, которые имеют
соответствующая специализация
std :: numeric_limits, текущий
версия теперь выбирает точность
матч.