2009-08-08 3 views
21

Quando si utilizza boost::program_options, come si imposta il nome di un argomento per boost::program_options::value<>()?Quando si utilizza boost :: program_options, come si imposta il nome dell'argomento?

#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; 
} 

Il codice di cui sopra dà:

--width arg   Give width 

Quello che voglio è quello di sostituire il nome arg con qualcosa di più descrittivo come NUM:

--width NUM   Give width 

risposta

7

Nelle versioni recenti di Boost (testato solo per > = 1.61) questo è completamente supportato.Sotto una leggera modifica del primo esempio nel tutorial, dove "LEVEL" viene stampato al posto di "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

3

può sostituire arg con qualcosa di diverso tramite la variabile globale boost::program_options::arg:

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

Tuttavia, poiché è una variabile globale, non aiuta molto a risolvere il problema quando più opzioni potrebbero richiedere argomenti diversi.

9

La classe program_options::value_semantic non parametrizza il nome dell'argomento, quindi penso che sarà necessario definire la propria classe. Qualcosa di simile a questo:

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"); 

Questo dovrebbe dare qualcosa di simile:

--witdh foo give width 
+3

Il distruttore per 'boost :: :: program_options options_description' apparentemente cerca di faccio un 'free()' su 'arg', quindi ho dovuto fare' my_arg_type * arg = new my_arg_type ("foo"); ' – eater

-3

L'approccio data dal Codebender è l'unico che si può usare. Questo è in realtà intenzionale - l'uso di "NUM" per nome dell'argomento sembra essere una micro-ottimizzazione che non vale la pena fare. Una buona descrizione dell'opzione dovrebbe anche dire che tipo di argomento è previsto.

+5

Chiamarlo" micro-ottimizzazione "è una specie di stupido, considerando che praticamente ogni singolo l'applicazione da riga di comando sulla terra lo fa. Devo ancora vederne uno solo che non dia i suoi argomenti propri tipi o nomi. – Grumbel

+0

Pensi che "stupido" sia la terminologia giusta da usare quando si discutono i potenziali cambiamenti con un manutentore di una libreria libera? –

+1

Mi sono appena incazzato quando peolpe mi ha detto che una funzionalità che viene utilizzata da ogni singola applicazione da riga virtuale è "non vale la pena farlo" in boost :: program_options. – Grumbel

8

Nella versione corrente di boost (1.53) non è più necessario creare la propria classe come proposto da Tim Sylvester. È possibile utilizzare: boost :: program_options :: typed_value. Su quale value_name può essere configurato.

#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; 
} 

visualizzerà un nome dell'argomento configurato:

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

Tanto per il disprezzo di Vladimir per questo tipo di "micro-ottimizzazione". ;-) – DevSolar

+0

Boost ora ha un valore '() sovraccarico che puoi chiamare' value_name() 'direttamente senza fare" raw "' new', vedi [la mia risposta] (http://stackoverflow.com/questions/1249646/when-using-boostprogram-options-how-does-one-set-the-name-of-the-argument/39934452 # 39934452) – TemplateRex

+0

grazie per aver notato – daminetreg

0

daminetreg's answer opere, ma può essere un po 'prolissa quando viene utilizzato per un sacco di voci di opzione. Ho appena messo insieme un sovraccarico per il modello value<T>(T* v) di costruire le mie value_sematic s con un ulteriore value_name: usando

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;   
} 

è possibile creare e aggiungere un nuovo program_option come questo:

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

(Nota: questo non affronta tutti gli altri modelli di costruzione, in particolare non il costruttore predefinito value() che l'OP desidera utilizzare)

+0

Boost.Program_options ora ha questo sovraccarico, vedere [la mia risposta ] (http://stackoverflow.com/questions/1249646/when-using-boostprogram-options-how-does-one-set-the-name-of-the-argument/39934452#39934452)! – TemplateRex