【问题标题】:How to use options for both command line and hierarchical config file with Boost Program_Options如何通过 Boost Program_Options 使用命令行和分层配置文件的选项
【发布时间】:2020-03-02 13:05:19
【问题描述】:

假设我有一个程序采用以下命令行选项:

$ prog1 --foo 1

我还有一个采用这种分层格式的配置文件,foo 参数位于 prog1 范围内:

[prog1]
foo = 42

我对Boost::program_options的理解是命令行选项的定义类似于:

description.add_options()
    ("foo", "Set foo value");

但是我希望配置文件中的值是默认值(作为调用store() 两次的结果,首先是命令行描述,然后是配置文件描述),能够被命令覆盖-line 选项,但我相信配置文件选项必须声明为:

description.add_options()
    ("prog1.foo", "Set foo value");

注意这里prog1.foo的使用,尤其是prog1.前缀。

所以我的问题是,如果您使用分层配置文件选项,您如何将这些与命令行选项相关联? IE。如何使--fooprog1.foo 在Storage 对象中表示相同的配置值?

【问题讨论】:

    标签: c++ boost config command-line-arguments boost-program-options


    【解决方案1】:

    我已经学到了足够的知识来回答我自己的问题。希望有一天这会对某人有所帮助,因为 Boost::Program_Options 文档没有涵盖这一点。

    如果您创建这样的分层配置选项(此记录在案):

        config_only_opts.add_options()
            ("section.option", po::bool_switch(), "Some option");
    

    并将其传递给parse_command_line()parse_config_file()

    那么配置文件将如下所示:

    [section]
    option=1
    

    命令行选项看起来像这样(没有记录):

    --section.option
    

    因此,分层选项转换为虚线命令行选项。因此,我希望这样:

    [one.two]
    three=4
    

    等同于以下配置选项:

    --one.two.three=4
    

    应用于命令行或配置文件选项的默认值以您期望的方式应用,具体取决于调用store() 的顺序。

    如果您想将任意命令行选项(例如 --foo)与分层(或平面)配置文件值(例如 bar.baz)相关联,则可以将前者注册为 parse_command_line(),后者注册为parse_config_file(),但为每个引用 same 存储变量:

        bool foo;
    
        po::options_description cmdline_opts;
        cmdline_only_opts.add_options()
            ("foo", po::value<bool>(&foo), "Foo")
            ;
    
        po::options_description config_file_opts;
        config_only_opts.add_options()
            ("bar.baz", po::value<bool>(&foo))
            ;
    
        po::variables_map vm;
        po::store(po::parse_command_line(argc, argv, cmdline_opts), vm);
        po::store(po::parse_config_file("config.file", config_file_opts, true /* allow unregistered */), vm);
        po::notify(vm);
    

    现在您可以使用--foo

    [bar]
    baz=X
    

    设置变量foo。唯一需要注意的是,您不能再使用 vm[XXX].as&lt;T&gt;() 其中“XXX”是“foo”或“bar.baz”来访问该值 - 只需使用引用的存储变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 2019-01-16
      • 1970-01-01
      • 2011-05-10
      相关资源
      最近更新 更多