有没有办法为参数设置一组允许的输入变量?例如,参数“arg”只能包含“cat”和“dog”等字符串值。
答案 0 :(得分:24)
您可以使用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'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")
;
答案 1 :(得分:7)
一种非常简单的方法是将“animal”作为普通字符串,并在通知您测试并在需要时抛出。
if (vm.count("animal") && (!(animal == "cat" || animal == "dog")))
throw po::validation_error(po::validation_error::invalid_option_value, "animal");
答案 2 :(得分:1)
我已经浏览了Boost.Program_options文档,对我来说,你是否可以做到这一点并不是很明显。我得到的印象是该库主要关注解析命令行,而不是验证它。您可能能够使用custom validator进行操作,但这会导致在输入错误时抛出异常(这可能是比您想要的更严重的错误)。我认为这个功能更适合确保你真正得到一个字符串,而不是它是“猫”或“狗”。
我能想到的最简单的解决方案是让库正常解析命令行,然后稍后添加您自己的代码以验证--arg
已设置为cat
或dog
。然后,您可以打印错误并退出,恢复到某个合适的默认值,或者您喜欢的任何内容。