提升program_options与构成()和implicit_value()不是和QUOT;组成" [英] Boost program_options with composing() and implicit_value() are not "composed"

查看:138
本文介绍了提升program_options与构成()和implicit_value()不是和QUOT;组成"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个选项的情况下升压program_options(v1_49)(),也隐含()的一个问题定义为合成。我的目的是实现与Perl类似的方式做一个-D选项,这样就可以做到-D或-Dname并多次使用。我options_description是:

I am having a problem with boost program_options (v1_49) in the case of an option defined as composing() and also implicit(). My intent is to implement a -D option similar to the way perl does, so that you can do -D or -Dname and use it multiple times. My options_description is:

(  "debug,D",
   bpo::value<vector<string> >()
         ->composing()
         ->implicit_value(vector<string>(1,"1")),
   "Set debug level."
),

这似乎在大多数情况下工作正常,但每当-D没有值出现在命令行中,所有早期值都被清除,例如:

This seems to work OK in most cases, but whenever -D with no value appears on the command line, all earlier values are erased, e.g.:

$ ./a.out -D abc -D 255 -D xyz
variables_map["debug"] = {"abc", "255", "xyz"}

$ ./a.out -D -D 255 -D xyz
variables_map["debug"] = {"1", "255", "xyz"}

$ ./a.out -D abc -D -D xyz
variables_map["debug"] = {"1", "xyz"}

$ ./a.out -D abc -D 255 -D
variables_map["debug"] = {"1"}

我想我明白为什么发生这种情况,内含价值{1}替换而不是增加其现有的载体。有什么我能做得到这个工作,或者是它的boost :: program_options的限制?

I think I see why this happens, the implicit value {"1"} replaces the existing vector instead of adding to it. Is there something I can do to get this to work or is it a limitation of boost::program_options?

推荐答案

下面是不需要修改升压源的解决方法。如果分开解析和存储任务,然后可以修改中间的boost :: program_options :: parsed_options 选项向量。向量的每个元素包含的std :: string的键和的std ::矢量&lt;标准::字符串&GT; 值。解决方法依赖于以下事实,对于隐式值,值的该矢量是空的。如果我们扫描 parsed_options 隐式的价值观和明确它们分配一个值,那么他们就不会破坏相同的密钥的previous值。这里的工作code:

Here's a workaround that doesn't require modifying boost sources. If you separate the parse and store tasks then you can modify the intermediate boost::program_options::parsed_options vector of options. Each element of the vector contains the std::string key and a std::vector<std::string> of values. The workaround relies on the fact that for implicit values, that vector of values is empty. If we scan parsed_options for implicit values and explicitly assign them a value then they don't clobber previous values of the same key. Here's working code:

#include <iostream>
#include <string>
#include <vector>
#include <boost/foreach.hpp>
#include <boost/program_options.hpp>

namespace po = boost::program_options;

namespace std {
   // This overload is needed to use composed options.
   static std::ostream& operator<<(
      std::ostream& os,
      const std::vector<std::string>& v) {
      os << '{';
      BOOST_FOREACH(const std::string& s, v) {
         if (&s != &*v.begin())
            os << ", ";
         os << '"' << s << '"';
      }
      os << '}';
      return os;
   }
}

int main(int argc, char *argv[]) {
   po::options_description desc("Allowed options");
   desc.add_options()
      ("debug,D",
       po::value<std::vector<std::string> >()
       ->composing()
       ->implicit_value(std::vector<std::string>(1,"1")),
       "Set debug level.");

   // Just parse the options without storing them in the map.
   po::parsed_options parsed_options = po::command_line_parser(argc, argv)
      .options(desc)
      .run();

   // Implicit option values are empty, replace with default value.
   BOOST_FOREACH(po::option& o, parsed_options.options) {
      if (o.string_key == "debug" && o.value.empty())
         o.value.push_back("1"); // default value is "1"
   }

   // Now store and earlier values aren't clobbered.
   po::variables_map vm;
   po::store(parsed_options, vm);
   po::notify(vm);

   std::cout << "variables_map[\"debug\"] = "
             << (vm.count("debug") ?
                 vm["debug"].as<std::vector<std::string> >() :
                 std::vector<std::string>())
             << '\n';
   return 0;
}

和这里的那些相同的测试用例:

And here's those same test cases:

$ ./a.out -D abc -D 255 -D xyz
variables_map["debug"] = {"abc", "255", "xyz"}

$ ./a.out -D -D 255 -D xyz
variables_map["debug"] = {"1", "255", "xyz"}

$ ./a.out -D abc -D -D xyz
variables_map["debug"] = {"abc", "1", "xyz"}

$ ./a.out -D abc -D 255 -D
variables_map["debug"] = {"abc", "255", "1"}

这篇关于提升program_options与构成()和implicit_value()不是和QUOT;组成&QUOT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆