2009-11-14 2 views
9

Когда я построить экземпляр подталкивания :: options_description какПредела точность на станде :: соиЬ значения по умолчанию в повышении :: options_description

options.add_options() 
    ("double_val", value(&config.my_double)->default_value(0.2), "it's a double"); 

, а затем хочу иметь автоматический вывод из опций, которые доступны для моей программы, и поставить

std::cout << options << std::endl; 

значение по умолчанию 0,2 показан с слишком высокой точностью, которая эффективно загромождает свой выход, когда у меня есть длинные имена переменных:

--double_val (=0.20000000000000001) it's a double 

к сожалению, до вызова STD :: cout.precision не помогло:

cout.precision(5); 
std::cout << options << std::endl; 

это приводит еще к тому же выход:/

У вас есть какие-либо идеи о том, как ограничить отображение значения по умолчанию для меньших позиций?

С наилучшими пожеланиями, христианские

ответ

10

boost/program_options/value_semantic.hpp С: (! Никогда не уверен, что с Boost)

/** 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; 
    } 

Так что реализация мертв просто. Попытка перенастроить ваш ostream для того, чтобы форматирование вышло, как вы хотите, не будет работать, потому что значение по умолчанию просто преобразуется в строку в автономном ostringstream (внутри lexical_cast).

Таким образом, простым обходным путем является добавление желаемого строкового представления в качестве второго аргумента в default_value. Затем вы можете распечатать его, как хотите (в том числе и вовсе, если передать пустую строку). Как так:

value(&config.my_double)->default_value(0.2, "0.2") 

Чем больше «enterprisey» способ выполнить то же самое было бы реализовать свой собственный тип, который будет обернуть double, будет использоваться для config.my_double, и обеспечить строительство от и принуждения к double, и ваш очень собственный ostream& operator<< с точно заданным форматированием. Однако я не предлагаю этот подход, если вы не пишете библиотеку, требующую общности.

С буста лексических примечаниями В ролях:

Предыдущая версия lexical_cast используется точность потока по умолчанию для чтения и записи с плавающей точкой чисел. Для чисел, которые имеют , соответствующая специализация std :: numeric_limits, текущая версия теперь выбирает точность до .

3

Чтобы избежать процитировать вручную:

#define QUOTE(x) #x 
#define stringize(x) QUOTE(x) 

#define MY_DOUBLE_DEFAULT 0.2 

value(&config.my_double)->default_value(MY_DOUBLE_DEFAULT, stringize(MY_DOUBLE_DEFAULT)) 
Смежные вопросы