【问题标题】:default and implicit arguments in boost program optionsboost 程序选项中的默认和隐式参数
【发布时间】: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 语法。

【问题讨论】:

标签: c++ boost g++


【解决方案1】:

来自docs,强调我的:

typed_value * implicit_value(const T & v);

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

所以当你写的时候:

$ ./opttest --writeMappings stuff

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

$ ./opttest --writeMappings=stuff

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

【讨论】:

  • 哇——我不敢相信我错过了。奇怪的是,这意味着在$ ./opttest --writeMappings stuff 产生writeMappings = stuff 的替代环境中产生的结果实际上是意外行为,对吧?除了意外行为之外,我无法解释 . . . 意外。感谢您的快速回复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-30
  • 2011-12-31
  • 1970-01-01
  • 2012-03-14
  • 2011-01-21
  • 2011-07-20
  • 1970-01-01
相关资源
最近更新 更多