У меня был тот же вопрос, но я отказался от него.
Я считаю, что способ сделать это - вызвать program_options::command_line_parser::extra_style_parser()
, передав ему функцию, которая берет вектор строки по ссылке и возвращает вектор option
с (см. style_parser
typedef в cmdline .hpp ).
Ваша функция должна будет обнаружить, что первый токен является "-", создать новый объект option
, поместить все остальные токены на входе в вектор значений option
и очистить вход вектор. См. program_options::detail::cmdline::parse_long_option
и т. Д. В libs/program_options/src/cmdline.cpp
, с чего можно начать.
Возможно, вам потребуется зарегистрировать определенное значение параметра, чтобы использовать его, чтобы вы могли легко найти этот специальный объект option
в конце анализа и извлечь из него набор дополнительных неопционных параметров.
Хотел бы я дать вам некоторый код, но я так и не удосужился на самом деле сделать это, в итоге я просто взял дополнительные параметры по одному на строку в stdin.
редактирование:
Мне было жаль указывать вам направление, которое не решило проблему, поэтому я вернулся и заставил его работать. Проблема в том, что ваш позиционный аргумент не был настроен на прием нескольких токенов, и вы не заполняли value
. Код program_options
ожидает обоих или не работает.
Вот полный код, который работает для меня:
#include <boost/program_options.hpp>
#include <iostream>
namespace po = boost::program_options;
typedef std::vector<std::string> stringvec;
std::vector<po::option> end_of_opts_parser(stringvec& args) {
std::vector<po::option> result;
stringvec::const_iterator i(args.begin());
if (i != args.end() && *i == "--") {
for (++i; i != args.end(); ++i) {
po::option opt;
opt.string_key = "pargs";
opt.value.push_back(*i); // <== here
opt.original_tokens.push_back(*i);
result.push_back(opt);
}
args.clear();
}
return result;
}
int main(int argc, char* argv[])
{
po::options_description desc("Allowed Options");
desc.add_options()
("help,h", "produce help message")
("pargs", po::value<stringvec>()->multitoken(), "positional arguments");
// and here ^^^^^^^^^^^^^
po::command_line_parser clparser(argc, argv);
clparser.extra_style_parser(end_of_opts_parser);
po::variables_map vm;
po::store(clparser.options(desc).run(), vm);
po::notify(vm);
bool const help = !vm["help"].empty();
std::cout << "help = " << help << " - ";
// in addition, you don't need to use a separate vector of strings:
stringvec const& pargs = vm["pargs"].as<stringvec>();
std::copy(pargs.begin(), pargs.end(),
std::ostream_iterator<std::string>(std::cout, ","));
return 0;
}
При запуске с -h -- foo bar baz
печатается help = 1 - foo,bar,baz,
.