2009-08-08 6 views
21

Al usar boost::program_options, ¿cómo configuro el nombre de un argumento para boost::program_options::value<>()?Al utilizar boost :: program_options, ¿cómo se establece el nombre del argumento?

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

El código anterior da:

--width arg   Give width 

Lo que quiero es reemplazar el nombre arg con algo más descriptivo, como NUM:

--width NUM   Give width 

Respuesta

7

En versiones recientes de Boost (solo probado para > = 1.61) esto es totalmente compatible.A continuación una ligera modificación del primer ejemplo en el tutorial, donde "NIVEL" se imprime en lugar de "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

Uno puede sustituir arg con algo diferente a través la variable global boost::program_options::arg:

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

Pero como se trata de una variable global, no ayuda mucho solucionar el problema cuando varias opciones pueden requerir argumentos diferentes.

9

El program_options::value_semantic clase no parametrizar el nombre del argumento, así que creo que tendrá que definir su propia clase. Algo como esto:

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

Esto debería dar algo como:

--witdh foo give width 
+3

El destructor para 'impulso :: :: program_options options_description' aparentemente trata de hacer un 'free()' en 'arg', así que tuve que hacer' my_arg_type * arg = new my_arg_type ("foo"); ' – eater

-3

El enfoque dado por Codebender es el único que puede utilizar. Esto es realmente intencional: usar "NUM" para el nombre del argumento parece ser una micro-optimización que no vale la pena. Una buena descripción de la opción también debe indicar qué tipo de argumento se espera.

+5

Llamarlo" micro-optimización "es algo estúpido, considerando que casi todos y cada uno aplicación de línea de comandos en la tierra lo hace. Aún no he visto ninguno que no dé a sus argumentos los tipos o nombres adecuados. – Grumbel

+0

¿Crees que "estúpido" es la terminología correcta para usar cuando se debaten cambios potenciales con un mantenedor de una biblioteca gratuita? –

+1

Me cabrea un poco cuando alguien me dice que una característica que se usa por cada aplicación de línea de comando virtual "no vale la pena" en boost :: program_options. – Grumbel

8

En la versión actual de boost (1.53) ya no es necesario crear su propia clase, como propuso Tim Sylvester. Es posible usar: boost :: program_options :: typed_value. En que value_name se puede configurar.

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

mostrará un nombre de argumento configurado:

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

Tanto por el desdén de Vladimir por este tipo de "micro-optimización". ;-) – DevSolar

+0

Boost ahora tiene una sobrecarga de 'valor ()' que se puede llamar 'value_name()' en directo sin hacer "raw" 'new', ver [mi respuesta] (http://stackoverflow.com/questions/1249646/when-using-boostprogram-options-how-does-one-set-the-name-of-the-argument/39934452 # 39934452) – TemplateRex

+0

gracias por notar – daminetreg

0

daminetreg's answer obras, pero puede ser un poco más detallado cuando se utiliza para una gran cantidad de entradas de opción. Yo sólo hackeado una sobrecarga para la plantilla value<T>(T* v) para construir mis value_sematic s con un adicional 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;   
} 

puede crear y añadir un nuevo program_option así:

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

(Nota: este no aborda todas las demás plantillas de construcción, especialmente el constructor predeterminado value() que el OP quiere usar)

+0

Boost.Program_options ahora tiene esta sobrecarga, ver [mi respuesta ] (http://stackoverflow.com/questions/1249646/when-using-boostprogram-options-how-does-one-set-the-name-of-the-argument/39934452#39934452)! – TemplateRex

Cuestiones relacionadas