Ao usar boost :: program_options, como se definir o nome do argumento?
-
12-09-2019 - |
Pergunta
Ao usar boost::program_options
, como faço para definir o nome de um argumento para 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;
}
O código acima dá:
--width arg Give width
O que eu quero é para substituir o nome arg
com algo mais descritivo como NUM
:
--width NUM Give width
Solução
Em versões recentes do Impulso (somente testado para> = 1.61), este é totalmente suportado. Abaixo uma ligeira modificação do primeiro exemplo no tutorial, onde "LEVEL" é impresso em vez 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")
;
Outras dicas
A classe program_options::value_semantic
não parametrizar o nome do argumento, então eu acho que você terá que definir sua própria classe. Algo parecido com isto:
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");
Isto deve dar algo como:
--witdh foo give width
Na versão atual de aumento (1,53), você não precisa mais fazer sua própria classe como Tim Sylvester proposto. É possível usar: boost :: program_options :: typed_value. Em que value_name pode ser configurado.
#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;
}
Será exibido um nome argumento configurado:
Usage:
-s [ --some-option ] NUM The option
Pode-se substituir arg
com algo diferente através da variável global
boost::program_options::arg
:
boost::program_options::arg = "NUM";
Mas como é que uma variável global, isso não ajuda muito a resolver o problema quando a opção múltipla pode exigir diferentes argumentos.
de daminetreg obras, mas pode ser um pouco verboso quando usado para os lotes de entradas de opção. Eu só cortei juntos uma sobrecarga para o modelo value<T>( T* v )
para construir meus value_sematic
s com um value_name
adicional: 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;
}
Você pode criar e adicionar um novo program_option assim:
int width;
desc.add_options()
("width", boost::program_options::value<int>( &width, "NUM"),
"Give width");
(Nota: esta não aborda todos os outros modelos de construção, especialmente não o construtor value()
padrão que o OP quer usar)
A abordagem dada pela Codebender é o único que você pode usar. Esta é realmente intencional - usando "NUM" para o nome do argumento parece ser micro-otimização que não vale a pena fazer. Uma boa descrição da opção também deve dizer que tipo de argumento é esperado.