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

default and implicit arguments in boost program options

本文关键字:参数 默认 程序 选项 boost      更新时间:2023-10-16

我看到boost program_options有一些奇怪的行为。我有一个选项,它有一个默认的隐式值。为了使我的程序具有广泛兼容的二进制文件,我在Holy Build Box下编译它,它似乎工作得很好。然而,我遇到的问题是,当我为这个选项(即--writeMappings ./somefile.txt)提供这个预编译的可执行文件时,结果被错误地解析。而不是将参数./somefile.txt映射到选项--writeMappings, boost::program_options认为--writeMappings选项的参数是空的,并且还有另一个选项,即具有参数./somefile.txt的空字符串""

我将变量map存储在一个JSON文件中,这里的示例准确地演示了我所看到的行为。有人知道为什么会发生这种情况吗?我认为这不是正确的行为。奇怪的是,当我在Holy Build Box的之外编译相同的代码时(使用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语法一起工作。

来自文档,强调我的:

typed_value * implicit_value(const T & v);

指定一个隐式值,如果给出了该选项,但没有相邻值,则使用该值。使用这意味着显式值是可选的,但如果给定,必须严格接近选项,即:'-ovalue'或'——option=value'。输入'-o'或'——option'将导致应用隐式值。

所以当你写:

$ ./opttest --writeMappings stuff

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

$ ./opttest --writeMappings=stuff

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