При использовании boost :: program_options, как установить имя аргумента? - PullRequest
22 голосов
/ 08 августа 2009

Как использовать 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

Ответы [ 6 ]

9 голосов
/ 09 августа 2009

Класс 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
8 голосов
/ 08 октября 2016

В последних версиях Boost (протестировано только для> = 1.61) это полностью поддерживается. Ниже приведена небольшая модификация первого примера в руководстве, где вместо «arg» печатается «LEVEL»:

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

Живой пример

8 голосов
/ 24 апреля 2013

В текущей версии boost (1.53) вам больше не нужно создавать свой собственный класс, как предложил Тим Сильвестр. Можно использовать: boost :: program_options :: typed_value. На какое значение_имя может быть настроено.

#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
3 голосов
/ 08 августа 2009

Можно заменить arg чем-то другим через глобальную переменную boost::program_options::arg

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

Но так как это глобальная переменная, это не сильно помогает решить проблему, когда множественный вариант может потребовать разных аргументов.

0 голосов
/ 10 февраля 2014

ответ daminetreg работает, но он может быть немного многословным, когда используется для большого количества записей опций. Я просто взломал перегрузку для шаблона value<T>( T* v ), чтобы создать мои value_sematic s с дополнительным 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");

(Примечание: это не относится ко всем другим шаблонам конструирования, особенно к конструктору value() по умолчанию, который ОП хочет использовать)

0 голосов
/ 10 августа 2009

Подход Codebender - единственный, который вы можете использовать. Это на самом деле преднамеренно - использование «NUM» для имени аргумента является микрооптимизацией, которую не стоит делать. В хорошем описании опции также должно быть указано, какой аргумент ожидается.

...