J'ai deux questions connexes:
Quelle est la manière la plus simple de permettre le passage d'une série de valeurs, en utilisant les options du programme Boost? Mon objectif est d'éviter prog --opt 1 --opt 2 --opt 3
et avoir prog --opt 1 2 3
au lieu.
Quelle est la façon la plus simple d'avoir une option qui prend exactement deux nombres, par ex. prog --opt 137 42
?
(Je n'ai pas besoin de paramètres de programme "gratuits".)
Pour la première partie, cela devrait fonctionner
namespace po = boost::program_options;
po::option_descriptions desc("");
desc.add_options()
("opt", po::value<std::vector<int> >()->multitoken(), "description");
La deuxième partie, nécessite un peu plus de travail. La fonction po::value
renvoie un po::typed_value< T, charT >
sur lequel vous devrez remplacer le comportement de plusieurs fonctions, comme suit
template< typename T, typename charT = char >
class fixed_tokens_typed_value : public po::typed_value< T, charT > {
unsigned _min, _max;
typedef po::typed_value< T, charT > base;
public:
fixed_tokens_typed_value( T * t, unsigned min, unsigned max )
: _min(min), _max(max), base( t ) {
base::multitoken();
}
virtual multi_typed_value* min_tokens( unsigned min ) {
_min = min;
return *this;
}
unsigned min_tokens() const {return _min;}
virtual multi_typed_value* max_tokens( unsigned max ) {
_max = max;
return *this;
}
unsigned max_tokens() const {return _max;}
base* zero_tokens() {
_min = _max = 0;
base::zero_tokens();
return *this;
}
}
qui doit être accompagné de
template< typename T >
fixed_tokens_typed_value< T >
fixed_tokens_value(unsigned min, unsigned max) {
return fixed_tokens_typed_value< T >(0, min, max ); }
template< typename T >
fixed_tokens_typed_value< T >
fixed_tokens_value(T * t, unsigned min, unsigned max) {
fixed_tokens_typed_value< T >* r = new
fixed_tokens_typed_value< T >(t, min, max);
return r; }
Ensuite
desc.add_options()
("opt", po::fixed_tokens_value<std::vector<int> >(2,2), "description");
devrait marcher. Je n'ai pas encore eu l'occasion de le tester, il contient donc probablement quelques bugs. Mais, au minimum, devrait vous donner une idée de ce dont vous avez besoin.
C'est une réponse tardive mais j'espère que cela aide quelqu'un. Vous pouvez facilement utiliser la même technique dans l'élément # 1, sauf que vous devez ajouter une autre validation sur le nombre d'éléments dans votre vecteur:
de l'exemple de rcollyer:
namespace po = boost::program_options;
po::option_descriptions desc("");
desc.add_options()
("opt", po::value<std::vector<int> >()->multitoken(), "description");
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
vector<int> opts;
if (!vm["opt"].empty() && (opts = vm["opt"].as<vector<int> >()).size() == 2) {
// good to go
}