English 中文(简体)
Limit the precision on std::cout of default values in boost::options_description
原标题:

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.

To avoid having to quote by hand:

#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))




相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签