boost程序选项中的默认和隐式参数

时间:2016-09-06 14:30:04

标签: c++ boost g++

我看到一些使用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 语法。

1 个答案:

答案 0 :(得分:1)

来自docs,强调我的:

typed_value * implicit_value(const T & v);
     

指定隐式值,如果给出了该选项,则将使用该值,但不包含相邻值。使用这意味着显式值是可选的,但是如果给定,必须严格地与选项相邻,即:' - font'或'--option = value'。给'-o'或' - 选项'将导致隐含值被应用。

所以当你写:

$ ./opttest --writeMappings stuff

stuff与选项writeMappings不严格相邻,因此完全被解释为单独的选项。你必须写:

$ ./opttest --writeMappings=stuff

获取"stuff"而不是"-"的值。