Когда вы используете библиотеку Boost program_options
очень легко распечатать справку для вашей программы:
boost::program_options::variables_map options;
boost::program_options::options_description optionsDesc;
boost::program_options::positional_options_description positionalOptionsDesc;
//...
if(options.count("help"))
{
cerr << optionsDesc << endl;
}
Но как вы добавляете варианты из positional_options_description
к сообщению помощи? В уроке я вижу результат такой настройки в конце раздела:
http://www.boost.org/doc/libs/1_52_0/doc/html/program_options/tutorial.html#id2607297
Опция input-file
напечатан в справке, и это позиционно. Но я не вижу код
Есть ли встроенный способ распечатать его, как с options_description
или ты должен делать это вручную? Видимо <<
не работает для positional_options_description
ошибка компиляции:
error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
Обратите внимание, что описание потоковой передачи выводит только параметры. Он не печатает название программы или фактическое описание того, что делает программа. Вы должны вручную распечатать любой позиционный параметр, который у вас есть, как часть выходного сообщения:
Вместо
if (vm.count("help")) {
cout << "Usage: options_description [options]\n";
cout << desc;
return 0;
}
Вы могли бы легко сказать
if (vm.count("help")) {
cout << "Usage: " << argv[0] << " [options] <description of positional 1> <description of positional 2> ...\n";
cout << desc;
return 0;
}
Посмотрите на boost :: program_options :: positional_options_description.name_for_position (i)
Сообщение об ошибке что-то не связано, я забыл, что на самом деле что-то делать с cpp11
Вот что я делаю для автоматической печати позиционных опций:
void printUsage(const std::string &argv0)
{
std::ostream &os = std::cout;
os << "Usage:" << std::endl;
// print only basename of argv[0]
boost::filesystem::path p(argv0);
os << " " << p.filename().string();
os << " [options]";
std::string last = "";
int rep = 0;
for(int i = 0; i < positional_options_description_.max_total_count(); i++)
{
const std::string &n = positional_options_description_.name_for_position(i);
if(n == last)
{
if(!rep) os << " ...";
if(rep++ > 1000) break;
}
else
{
os << " " << n;
last = n;
rep = 0;
}
}
os << std::endl << std::endl;
os << options_description_ << std::endl;
}
Логика проверки повторяющихся имен аргументов необходима только в том случае, если у вас есть повторяющиеся параметры, которые могут повторяться бесконечное число раз, т. Е. С числом, равным -1, в противном случае вы можете немного упростить это, например, заменить if... else if ...
с os << " " << n;
,
В текущей (1.68) версии надстройки невозможно определить, является ли описание опции позиционным или нет, поэтому ничего не нужно делать для улучшения справки, например, исключая позиционные опции из печати.