When I construct a boost::options_description instance like
options.add_options()
("double_val", value(&config.my_double)->default_value(0.2), "it's a double");
and later want to have the automated output of the options that are available for my program, and put
std::cout << options << std::endl;
the default value 0.2 is shown with way too high precision, which effectively clutters my output when I have long variable names:
--double_val (=0.20000000000000001) it's a double
unfortunately, a prior call to std::cout.precision did not help:
cout.precision(5);
std::cout << options << std::endl;
this leads still to the same output :/
Do you have any ideas on how to limit the display of the default value to less positions?
Best regards, Christian
From 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;
}
So the implementation is dead simple (never a sure thing with Boost!). Trying to reconfigure your ostream to make the formatting come out as you want won't work, because the default value just gets converted to a string in a standalone ostringstream
(inside lexical_cast
).
So a simple workaround is to add your desired string representation as a second argument to default_value
. Then you can make it print however you want (including not at all, if you pass an empty string). Like so:
value(&config.my_double)->default_value(0.2, "0.2")
The more "enterprisey" way to accomplish the same thing would be to implement your own type which would wrap double
, be used for config.my_double
, and provide construction from and coercion to double
, and your very own ostream& operator<<
with exactly the formatting you desire. I don't suggest this approach, however, unless you're writing a library that demands generality.
From the Boost Lexical Cast notes:
The previous version of lexical_cast used the default stream precision for reading and writing floating-point numbers. For numerics that have a corresponding specialization of std::numeric_limits, the current version now chooses a precision to match.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With