我看到一些使用boost program_options的奇怪行为。我有一个default and implicit value的选项。为了使我的程序具有广泛兼容的二进制文件,我在Holy Build Box下编译它,这似乎运行良好。但是,我遇到的问题是,当我使用此选项的显式参数(即--writeMappings ./somefile.txt
)提供此预编译的可执行文件时,结果将被错误地解析。 boost :: program_options不是将参数./somefile.txt
映射到选项--writeMappings
,而是认为--writeMappings
选项的参数为空,还有另一个选项,即空字符串{{1它的参数为""
。
我将变量映射存储在JSON文件中,示例here完全展示了我所看到的行为。有谁知道为什么会这样?我认为这不是正确的行为。奇怪的是,当我在Holy Build Box中编译相同的代码 时(使用g ++ - 4.9.1而不是g ++ - 4.8.2),程序按预期工作,隐式参数被任何覆盖传递的显式参数。
以下是重现问题的最小示例:
./somefile.txt
我编译了以下内容:
#include <iostream>
#include <vector>
#include <boost/program_options.hpp>
int main(int argc, char* argv[]) {
using std::cerr;
using std::string;
namespace po = boost::program_options;
string fname;
po::options_description generic("\n"
"basic options");
generic.add_options()("version,v", "print version string")
(
"writeMappings", po::value<string>(&fname)->default_value("")->implicit_value("-"),
"If this option is provided, then the quasi-mapping results will be written out in SAM-compatible "
"format. By default, output will be directed to stdout, but an alternative file name can be "
"provided instead.");
po::options_description visible("options");
visible.add(generic);
po::variables_map vm;
try {
auto orderedOptions =
po::command_line_parser(argc, argv).options(visible).run();
po::store(orderedOptions, vm);
po::notify(vm);
std::cerr << "writeMappings = " << fname << '\n';
} catch (po::error& e) {
std::cerr << "Exception : [" << e.what() << "]. Exiting.\n";
std::exit(1);
}
return 0;
}
我得到以下输出以及相应的调用:
g++ -std=c++11 -o opttest main.cpp -L /home/boost_1_61_0/lib -I /home/boost_1_61_0/include -lboost_program_options
最后的调用是有问题的。鉴于明确的选择,我期待 $ ./opttest
writeMappings =
$ ./opttest --writeMappings
writeMappings = -
$ ./opttest --writeMappings stuff
writeMappings = -
。但是,我会注意到,当我使用替代语法时,它会被正确解析:
writeMappings = stuff
但是,我真的希望这可以使用更常见的 $ ./opttest --writeMappings=stuff
writeMappings = stuff
语法。
答案 0 :(得分:1)
来自docs,强调我的:
typed_value * implicit_value(const T & v);
指定隐式值,如果给出了该选项,则将使用该值,但不包含相邻值。使用这意味着显式值是可选的,但是如果给定,必须严格地与选项相邻,即:' - font'或'--option = value'。给'-o'或' - 选项'将导致隐含值被应用。
所以当你写:
$ ./opttest --writeMappings stuff
stuff
与选项writeMappings
不严格相邻,因此完全被解释为单独的选项。你必须写:
$ ./opttest --writeMappings=stuff
获取"stuff"
而不是"-"
的值。