如何使用 Boost 的命令行和分层配置文件的选项 Program_Options

How to use options for both command line and hierarchical config file with Boost Program_Options

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

$ prog1 --foo 1

我也有一个配置文件是这种分层格式,foo参数在prog1范围内:

[prog1]
foo = 42

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

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

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

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

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

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

我已经学到了足够的知识来回答我自己的问题。希望有一天这会对某人有所帮助,因为 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(),但为每个引用 相同的 存储变量:

    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<T>(),其中 "XXX" 是 "foo" 或 "bar.baz" 来访问值 - 只需使用引用的存储变量。