При использовании boost:: program_options, как установить имя аргумента?
При использовании 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
Ответы
Ответ 1
В последних версиях Boost (проверено только нa >= 1,61) это полностью поддерживается. Ниже небольшой модификации первого примера в учебнике, где вместо "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
Ответ 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
Ответ 3
В текущей версии boost (1.53) вам больше не нужно создавать свой собственный класс, как предложил Тим Сильвестр. Можно использовать: 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
Ответ 4
Можно заменить arg
чем-то другим через глобальную переменную
boost::program_options::arg
:
boost::program_options::arg = "NUM";
Но поскольку это глобальная переменная, это не помогает решить проблему, когда для нескольких параметров могут потребоваться разные аргументы.
Ответ 5
daminetreg answer работает, но он может быть немного подробным при использовании для множества записей параметров. Я только что взломал перегрузку для шаблона value<T>( T* v )
, чтобы построить мой value_sematic
с дополнительным 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()
по умолчанию, который OP хочет использовать)
Ответ 6
Подход, данный Codebender, является единственным, который вы можете использовать. Это на самом деле намеренно - использование "NUM" для имени аргумента представляется микро-оптимизацией, которая не стоит делать. Хорошее описание опции должно также сказать, какой аргумент ожидается.