Опции программы Boost позволили установить входные значения - PullRequest
17 голосов
/ 11 января 2012

Есть ли способ установить допустимый набор входных переменных для параметров? Например, параметр «arg» может иметь только строковые значения, такие как «cat» и «dog».

Ответы [ 3 ]

24 голосов
/ 11 января 2012

Вы можете использовать пользовательский валидатор .Определите отдельный тип для вашего параметра, а затем перегрузите функцию validate для этого типа.

struct catdog {
  catdog(std::string const& val):
    value(val)
  { }
  std::string value;
};

void validate(boost::any& v, 
              std::vector<std::string> const& values,
              catdog* /* target_type */,
              int)
{
  using namespace boost::program_options;

  // Make sure no previous assignment to 'v' was made.
  validators::check_first_occurrence(v);

  // Extract the first string from 'values'. If there is more than
  // one string, it's an error, and exception will be thrown.
  std::string const& s = validators::get_single_string(values);

  if (s == "cat" || s == "dog") {
    v = boost::any(catdog(s));
  } else {
    throw validation_error(validation_error::invalid_option_value);
  }
}

Исключения, генерируемые из этого кода, ничем не отличаются от исключений, генерируемых для любого другого недопустимого значения параметра, поэтомувы уже должны быть готовы обработать их.

Используйте специальный тип опции вместо просто string, когда определяете свои опции:

desc.add_options()
  ("help", "produce help message")
  ("arg", po::value<catdog>(), "set animal type")
;

Я составил liveпример, демонстрирующий использование этого кода .

7 голосов
/ 15 сентября 2013

Очень простой подход состоит в том, чтобы иметь "животное" в качестве нормальной строки и после уведомления тестировать и бросать, если необходимо.

if (vm.count("animal") && (!(animal == "cat" || animal == "dog")))
        throw po::validation_error(po::validation_error::invalid_option_value, "animal");
1 голос
/ 11 января 2012

Я пролистал документацию Boost.Program_options, и мне совершенно не очевидно, можете ли вы это сделать. У меня складывается впечатление, что библиотека в первую очередь связана с разбором командной строки, а не с ее проверкой. Возможно, вам удастся что-то улучшить с помощью пользовательского валидатора , но это включает в себя генерирование исключений при получении неверных входных данных (что может быть более серьезной ошибкой, чем вы хотите). Я думаю, что эта функция больше ориентирована на то, чтобы убедиться, что вы действительно получили строку, а не то, что это была «кошка» или «собака».

Самое простое решение, которое я могу придумать, - это позволить библиотеке анализировать командную строку как обычно, а затем добавить свой собственный код позже, чтобы убедиться, что для --arg установлено значение cat или dog. Затем вы можете распечатать ошибку и выйти, вернуться к некоторому подходящему по умолчанию или как вам угодно.

...