限制boost :: options_description中std :: cout默认值的精度

时间:2009-11-14 17:22:10

标签: c++ precision cout boost-program-options

当我构建一个boost :: 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;

这仍然导致相同的输出:/

您对如何将默认值的显示限制在较少的位置有任何想法吗?

祝你好运, 基督教

2 个答案:

答案 0 :(得分:11)

来自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,并提供构造和强制到{{1} },以及您自己的double,其中包含您想要的格式。但是,除非你正在编写一个需要通用性的库,否则我不建议这种方法。

来自Boost Lexical Cast笔记:

  

以前版本的lexical_cast   使用默认的流精度   读写浮点数   数字。对于有数字的数字   相应的专业化   std :: numeric_limits,当前   版本现在选择精度   匹配。

答案 1 :(得分: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))