Using boost 1_55, I have a bool_switch() option, which is defined as:
使用boost 1_55,我有一个bool_switch()选项,定义如下:
bpo::options_description opts;
opts->add_options()
("foo", bpo::bool_switch(), "Enable foo.");
opts_map = new bpo::variables_map;
And it is parsed on the command line by:
它在命令行上通过以下方式解析:
bpo::store(bpo::parse_command_line(argc, argv, opts), *opts_map);
And also parsed in a config file by:
并通过以下方式解析配置文件:
ifstream ifs("foo.conf");
if (ifs.good()) {
bpo::store(bpo::parse_config_file(ifs, opts), *opts_map);
close(ifs);
}
The trouble is that it works fine on the command line by either specifying --foo
or not, but it is always false
(with second.defaulted() == true
) when I put it in the config file. I have tried the following in the config file:
问题是它在命令行上运行正常,通过指定--foo或不指定 - 但是当我把它放在配置文件中时它总是假的(使用second.defaulted()== true)。我在配置文件中尝试了以下内容:
foo
foo=true
foo=1
Other types of options (e.g. bpo::value<ANYTYPE>()
with or without composing()
) work fine both on the command line and also in the config file, only bool_switch()
options are not working.
其他类型的选项(例如bpo :: value
Any idea what I'm doing wrong? Or can you not use bool_switch()
options with parse_config_file()
?
知道我做错了什么吗?或者你不能在parse_config_file()中使用bool_switch()选项吗?
EDIT:
编辑:
A workaround is to use a value()
type with default_value()
and implicit_value()
:
解决方法是使用带有default_value()和implicit_value()的value()类型:
opts->AddOptions()("foo", bpo::value<bool>()->default_value(false)->implicit_value(true), "Enable foo.");
2 个解决方案
#1
1
I don't think what you're trying to do is presently allowed. Vladimir, the author of the program options library states
我不认为你现在想要做什么。程序选项库的作者弗拉基米尔说
I've changed bool_switch so that it does not accept any arguments. This also solves the problem with "arg (=0)" output.
我已经更改了bool_switch,因此它不接受任何参数。这也解决了“arg(= 0)”输出的问题。
There's one possible problem. For command line, we most likely don't want explicit value for bools. But in config file, the value is always present. This is the only case I know where single options description for command line and other sources is problematic -- if you describe an option with bool_switch, it can't be specified in config file.
有一个可能的问题。对于命令行,我们很可能不希望bools显式值。但是在配置文件中,值始终存在。这是我知道的唯一一种情况,其中命令行和其他源的单选项描述存在问题 - 如果您使用bool_switch描述选项,则无法在配置文件中指定。
Let's see if that's a problem.
让我们看看这是否有问题。
Note that this statement is nearly 10 years old, but I couldn't find any evidence it's no longer true when inspecting the source code in 1.55.
请注意,这个陈述已有近10年的历史,但在1.55中检查源代码时,我找不到任何证据。
#2
2
I'm currently using Boost 1.58 and support for boolean switch options in a config file works just fine.
我目前正在使用Boost 1.58并且在配置文件中支持布尔开关选项工作正常。
Config file (config.cfg):
配置文件(config.cfg):
log=ON
Code:
码:
#include <fstream>
#include <boost/program_options.hpp>
#include <iostream>
namespace prog_opts = boost::program_options;
//Notified function
void option_verbose(bool opt) {
std::cout << "Log ";
if (opt)
std::cout << "ON";
else
std::cout << "OFF";
std::cout << "\n";
}
int main (int argc, char* argv[]) {
prog_opts::options_description general("Options");
general.add_options()
("log", prog_opts::bool_switch()->notifier(&option_verbose), "logging")
;
// Assign the CLI args to the map
prog_opts::variables_map cli_map;
const prog_opts::basic_parsed_options< char >& cliopts = prog_opts::command_line_parser(argc, argv).options(general).run();
prog_opts::store(cliopts , cli_map);
// Get options from config
std::ifstream infile("config.cfg", std::ifstream::in);
store(parse_config_file(infile, general), cli_map);
notify(cli_map);
}
From using this, it appears that the behavior is:
从使用它,似乎行为是:
- If your option is present on the command line then that overrides the config file.
- 如果您的选项出现在命令行中,则会覆盖配置文件。
- If your option is not present on the command line then the config file option value is used instead.
- 如果命令行中没有您的选项,则使用配置文件选项值。
In the example code with log=ON in the config file, the option will always be ON. With it set to OFF, the option will only be enabled when running your application with the option --log.
在配置文件中带有log = ON的示例代码中,该选项将始终为ON。将其设置为OFF时,只有在使用选项--log运行应用程序时才会启用该选项。
Hope this helps.
希望这可以帮助。
#1
1
I don't think what you're trying to do is presently allowed. Vladimir, the author of the program options library states
我不认为你现在想要做什么。程序选项库的作者弗拉基米尔说
I've changed bool_switch so that it does not accept any arguments. This also solves the problem with "arg (=0)" output.
我已经更改了bool_switch,因此它不接受任何参数。这也解决了“arg(= 0)”输出的问题。
There's one possible problem. For command line, we most likely don't want explicit value for bools. But in config file, the value is always present. This is the only case I know where single options description for command line and other sources is problematic -- if you describe an option with bool_switch, it can't be specified in config file.
有一个可能的问题。对于命令行,我们很可能不希望bools显式值。但是在配置文件中,值始终存在。这是我知道的唯一一种情况,其中命令行和其他源的单选项描述存在问题 - 如果您使用bool_switch描述选项,则无法在配置文件中指定。
Let's see if that's a problem.
让我们看看这是否有问题。
Note that this statement is nearly 10 years old, but I couldn't find any evidence it's no longer true when inspecting the source code in 1.55.
请注意,这个陈述已有近10年的历史,但在1.55中检查源代码时,我找不到任何证据。
#2
2
I'm currently using Boost 1.58 and support for boolean switch options in a config file works just fine.
我目前正在使用Boost 1.58并且在配置文件中支持布尔开关选项工作正常。
Config file (config.cfg):
配置文件(config.cfg):
log=ON
Code:
码:
#include <fstream>
#include <boost/program_options.hpp>
#include <iostream>
namespace prog_opts = boost::program_options;
//Notified function
void option_verbose(bool opt) {
std::cout << "Log ";
if (opt)
std::cout << "ON";
else
std::cout << "OFF";
std::cout << "\n";
}
int main (int argc, char* argv[]) {
prog_opts::options_description general("Options");
general.add_options()
("log", prog_opts::bool_switch()->notifier(&option_verbose), "logging")
;
// Assign the CLI args to the map
prog_opts::variables_map cli_map;
const prog_opts::basic_parsed_options< char >& cliopts = prog_opts::command_line_parser(argc, argv).options(general).run();
prog_opts::store(cliopts , cli_map);
// Get options from config
std::ifstream infile("config.cfg", std::ifstream::in);
store(parse_config_file(infile, general), cli_map);
notify(cli_map);
}
From using this, it appears that the behavior is:
从使用它,似乎行为是:
- If your option is present on the command line then that overrides the config file.
- 如果您的选项出现在命令行中,则会覆盖配置文件。
- If your option is not present on the command line then the config file option value is used instead.
- 如果命令行中没有您的选项,则使用配置文件选项值。
In the example code with log=ON in the config file, the option will always be ON. With it set to OFF, the option will only be enabled when running your application with the option --log.
在配置文件中带有log = ON的示例代码中,该选项将始终为ON。将其设置为OFF时,只有在使用选项--log运行应用程序时才会启用该选项。
Hope this helps.
希望这可以帮助。