2009-08-08 3 views
21

При использовании boost::program_options, как установить имя аргумента для boost::program_options::value<>()?При использовании boost :: program_options, как задать имя аргумента?

#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 

ответ

7

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

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

3

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

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

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

9

Класс 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

Деструктор для 'повышение :: program_options :: options_description', видимо, пытается сделайте 'free()' on' arg', поэтому мне пришлось делать 'my_arg_type * arg = new my_arg_type (« foo »);' – eater

-3

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

+5

Вызов «микро-оптимизации» - это глупость, учитывая, что почти каждый это приложение командной строки на земле. Я еще не видел ни одного, который не дает его аргументов надлежащим типам или именам. – Grumbel

+0

Считаете ли вы, что «глупость» - это правильная терминология, которую следует использовать при обсуждении потенциальных изменений с сопровождающим бесплатной библиотекой? –

+1

Я просто немного разозлился, когда peolpe сообщила мне, что функция, которая используется виртуальным каждым приложением командной строки outthere, «не стоит делать» в boost :: program_options. – Grumbel

8

В текущей версии 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 
+2

Так много для презрения Владимира к такой «микро-оптимизации». ;-) – DevSolar

+0

У Boost теперь есть значение 'value ()' overload, которое вы можете вызвать 'value_name()' непосредственно, не делая «raw» 'new', см. [Мой ответ] (http://stackoverflow.com/questions/1249646/when-using-boostprogram-options-how-do-one-set-the-name-of-the-argument/39934452 # 39934452) – TemplateRex

+0

благодарит за замещение – daminetreg

0

daminetreg's 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 хочет использовать)

+0

Boost.Program_options теперь имеет эту перегрузку, см. [Мой ответ ] (http://stackoverflow.com/questions/1249646/when-using-boostprogram-options-how-does-one-set-the-name-of-the-argument/39934452#39934452)! – TemplateRex

 Смежные вопросы

  • Нет связанных вопросов^_^