【发布时间】:2016-09-06 14:30:03
【问题描述】:
我看到 boost program_options 的一些奇怪行为。我有一个带有default and implicit value 的选项。为了使我的程序具有广泛兼容的二进制文件,我在Holy Build Box 下编译它,这似乎运行良好。但是,我遇到的问题是,当我为这个预编译的可执行文件提供了这个选项的显式参数(即--writeMappings ./somefile.txt)时,结果被错误地解析了。而不是将参数./somefile.txt映射到选项--writeMappings,boost::program_options认为--writeMappings选项的参数是空的,还有另一个选项,空字符串"",它的参数是@ 987654330@.
我将变量映射存储在 JSON 文件中,示例 here 准确地演示了我所看到的行为。有谁知道为什么会发生这种情况?我认为这不是正确的行为。奇怪的是,当我在 Holy Build Box outside 编译相同的代码(使用 g++-4.9.1 而不是 g++-4.8.2)时,程序按预期工作,并且隐式参数被任何传递的显式参数。
这是重现问题的最小示例:
#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
但是,我真的希望它能够使用更常见的 --option argument 语法。
【问题讨论】:
-
请提供minimal reproducible example,并直接在问题中提供代码。
-
好的,我已经提供了一个 mcve。