【问题标题】:When using boost::program_options, how does one set the name of the argument?使用 boost::program_options 时,如何设置参数的名称?
【发布时间】:2009-08-08 19:06:17
【问题描述】:

使用boost::program_options时,如何设置boost::program_options::value<>()的参数名称?

#include <iostream>
#include <boost/program_options.hpp>

int main()
{
  boost::program_options::options_description desc;

  desc.add_options()
    ("width", boost::program_options::value<int>(),
     "Give width");

  std::cout << desc << std::endl;

  return 0;
}

以上代码给出:

  --width arg           Give width

我想要的是将 arg 名称替换为更具描述性的名称,例如 NUM

  --width NUM           Give width

【问题讨论】:

    标签: c++ boost boost-program-options


    【解决方案1】:

    在 Boost 的最新版本中(仅针对 >= 1.61 进行了测试),这是完全支持的。下面对教程中的第一个示例稍作修改,其中打印“LEVEL”而不是“arg”:

    po::options_description desc("Allowed options");
    desc.add_options()
        ("help", "produce help message")
        ("compression", po::value<int>()->value_name("LEVEL"), "set compression level")
    ;
    

    Live Example

    【讨论】:

      【解决方案2】:

      program_options::value_semantic 类没有参数化参数名称,所以我认为您必须定义自己的类。像这样的:

      struct my_arg_type
          : public boost::program_options::typed_value<int>
      {
          my_arg_type(std::string const& name)
              : boost::program_options::typed_value<int>(&my_value)
              , my_name(name)
              , my_value(0)
          {
          }
          std::string name() const { return my_name; }
          std::string my_name;
          int my_value;
      };
      
      boost::program_options::options_description desc;
      
      my_arg_type arg("foo");
      desc.add_options()
          ("width", &arg, "give width");
      

      这应该是这样的:

      --witdh foo    give width
      

      【讨论】:

      • boost::program_options::options_description 的析构函数显然试图在arg 上执行free(),所以我不得不这样做my_arg_type* arg = new my_arg_type("foo");
      【解决方案3】:

      在当前版本的 boost (1.53) 中,您不再需要像 Tim Sylvester 建议的那样创建自己的类。可以使用:boost::program_options::typed_value。可以在哪个 value_name 上配置。

      #include <iostream>
      #include <boost/program_options.hpp>
      using boost::program_options::typed_value;
      using boost::program_options::options_description;
      
      int main(int argc, char **argv) {
          options_description desc("Usage");
      
          int someValue;
          auto someOption = new typed_value<decltype(someValue)>(&someValue);
          someOption->value_name("NUM");
          desc.add_options()
              ("some-option,s", someOption, "The option\n");
      
          std::cout << desc << std::endl;
          return 0;
      }
      

      将显示配置的参数名称:

      Usage:
      -s [ --some-option ] NUM The option
      

      【讨论】:

      • 弗拉基米尔对这种“微优化”不屑一顾。 ;-)
      • Boost 现在有一个 value&lt;T&gt;() 重载,您可以直接调用 value_name() 而无需执行“原始”new,请参阅 my answer
      【解决方案4】:

      可以通过全局变量将arg 替换为不同的东西 boost::program_options::arg:

      boost::program_options::arg = "NUM";
      

      但由于这是一个全局变量,当多个选项可能需要不同的参数时,它对解决问题没有多大帮助。

      【讨论】:

        【解决方案5】:

        daminetreg's answer 有效,但在用于大量选项条目时可能会有点冗长。我刚刚为value&lt;T&gt;( T* v ) 模板编写了一个重载,以构造我的value_sematics 和一个额外的value_name:使用

        template<class T>
        typed_value<T>*
        value(T* v, const char * value_typename)
        {
            typed_value<T>* r = new typed_value<T>(v);
            r->value_name( value_typename );
        
            return r;        
        }
        

        您可以像这样创建和添加新的 program_option:

        int width;
        desc.add_options()
            ("width", boost::program_options::value<int>( &width, "NUM"),
             "Give width");
        

        (注意:这并没有解决所有其他构造模板,尤其是 OP 想要使用的默认 value() 构造函数)

        【讨论】:

        • Boost.Program_options 现在有这个重载,请参阅my answer!
        【解决方案6】:

        Codebender 提供的方法是您唯一可以使用的方法。这实际上是有意的——使用“NUM”作为参数名称似乎是不值得做的微优化。对选项的良好描述还应该说明预期的参数类型。

        【讨论】:

        • 称其为“微优化”有点愚蠢,考虑到地球上几乎每个命令行应用程序都会这样做。我还没有看到一个没有给它的参数提供正确的类型或名称。
        • 您认为“愚蠢”是与免费库的维护者讨论潜在更改时使用的正确术语吗?
        • 当人们告诉我虚拟的每个命令行应用程序使用的功能在 boost::program_options 中“不值得做”时,我有点生气。
        • 做个好人,伙计们。这不是我认为最重要的事情,但改变是否值得是做这项工作的人(或支付他们的人)的唯一决定。称之为学习体验;毕竟,这就是这个网站的重点。 (顺便说一句,弗拉基米尔,你的 cmets 真的不应该是一个“答案”,我怀疑这是投反对票的根源。)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-22
        • 1970-01-01
        • 2012-12-17
        相关资源
        最近更新 更多