C++ 使用boost::program_选项时,如何设置参数的名称?

C++ 使用boost::program_选项时,如何设置参数的名称?,c++,boost,boost-program-options,C++,Boost,Boost Program Options,使用boost::program\u options时,如何设置boost::program\u options::value()的参数名称 我想要的是将arg名称替换为更具描述性的名称,如NUM: --width NUM Give width 可以通过全局变量用不同的内容替换arg boost::程序选项::arg: boost::program_options::arg = "NUM"; 但是,由于这是一个全局变量,当多个选项可能需要不同的参数时,解决这个问题没有

使用
boost::program\u options
时,如何设置
boost::program\u options::value()
的参数名称

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

  --width NUM           Give width

可以通过全局变量用不同的内容替换
arg
boost::程序选项::arg

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

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

程序选项::值语义类没有参数化参数名称,因此我认为您必须定义自己的类。大概是这样的:

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");
int width;
desc.add_options()
    ("width", boost::program_options::value<int>( &width, "NUM"),
     "Give width");

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

在当前版本的boost(1.53)中,您不再需要像Tim Sylvester建议的那样创建自己的类。可以使用:boost::program\u options::typed\u value。可以在其上配置值\u 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;
}
可以,但是当用于很多选项条目时,可能会有点冗长。我刚刚为
value(T*v)
模板拼凑了一个重载,用一个额外的
value\u名称构建了我的
value\u语义

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;        
}
模板
输入值*
值(T*v,常量字符*值\u类型名)
{
类型化_值*r=新类型化_值(v);
r->value\u name(value\u typename);
返回r;
}
您可以创建并添加一个新的program_选项,如下所示:

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");
int width;
desc.add_options()
    ("width", boost::program_options::value<int>( &width, "NUM"),
     "Give width");
int宽度;
说明添加选项()
(“宽度”,boost::program_options::value(&width,“NUM”),
“给出宽度”);

(注意:这不涉及所有其他构造模板,特别是OP想要使用的默认
value()
构造函数)

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

po::选项描述描述(“允许选项”);
说明添加选项()
(“帮助”,“生成帮助消息”)
(“压缩”,po::value()->value_名称(“级别”),“设置压缩级别”)
;

考虑到地球上几乎每一个命令行应用程序都这么做,将其称为“微优化”有点愚蠢。我还没有看到一个参数没有给出正确的类型或名称。你认为这“愚蠢”吗在与免费库的维护人员讨论潜在更改时,使用的术语是否正确?当人们告诉我,在boost::program_options中,虚拟每个命令行应用程序使用的功能“不值得做”时,我有点生气。这不是我认为最重要的事情,而是一个改变是否值得做的是做这项工作的人(或付给他们的人)的唯一决定。称之为学习经历;毕竟,这就是这个网站的全部意义所在。(顺便说一句,弗拉基米尔,你的评论真的不应该是一个“答案”,我怀疑这是否决票的来源。)boost::program_options::options_description
的析构函数显然试图在
arg
上做一个
free()
,所以我不得不做
my_arg类型*arg=new my_arg类型(“foo”)弗拉基米尔对这种“微观优化”的蔑视到此为止Boost现在有一个
value()
重载,您可以直接调用
value\u name()
,而无需执行“原始”
new
,请参阅Boost.Program\u选项现在有这个重载,请参阅!
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;        
}
int width;
desc.add_options()
    ("width", boost::program_options::value<int>( &width, "NUM"),
     "Give width");
po::options_description desc("Allowed options");
desc.add_options()
    ("help", "produce help message")
    ("compression", po::value<int>()->value_name("LEVEL"), "set compression level")
;