Расширенные возможности программы позволяют устанавливать входные значения

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

Ответы

Ответ 1

Вы можете использовать функцию custom validator. Определите отдельный тип для своей опции, а затем перегрузите функцию 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 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")
;

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

Ответ 2

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

if (vm.count("animal") && (!(animal == "cat" || animal == "dog")))
        throw po::validation_error(po::validation_error::invalid_option_value, "animal");

Ответ 3

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

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