我正在尝试理解program_options自定义验证,以便将python代码转换为c ++代码
任何方式
我在示例中读到我必须重载验证功能
我试图在boost program_options文件中找到原始函数但是徒劳无功
任何人都可以告诉我原来的验证功能在哪里我会过载它
这是一个愚蠢的问题,但我想知道它是如何在默认情况下验证,以了解验证的概念及其如何完成
提前谢谢
答案 0 :(得分:1)
扩展我的一行评论,我总是发现boost :: program_options在参数验证方面有点不足。
结果我发现为每种选项类型编写自定义类通常更容易。通常,program_options使用operator>>
来解码选项值,因此如果重写此选项,您将有机会抛出program_options识别的异常。如果使用嵌套异常,则可以打印非常详细的错误诊断。
示例:
#include <boost/program_options.hpp>
#include <iostream>
#include <iomanip>
#include <sstream>
namespace po = boost::program_options;
// a custom option type
struct foo_or_bar {
std::string value;
// self-describing
static constexpr const char *option_name() { return "foo"; }
static constexpr const char *description() { return "single option only. value must be either foo or bar"; }
// check the value and throw a nested exception chain if it's wrong
void check_value() const
try {
if (value != "foo" and value != "bar") {
std::ostringstream ss;
ss << "value must be foo or bar, you supplied " << std::quoted(value);
throw std::invalid_argument(ss.str());
}
}
catch (...) {
std::throw_with_nested(po::validation_error(po::validation_error::invalid_option_value, option_name()));
}
// overload operators
friend std::istream &operator>>(std::istream &is, foo_or_bar &arg) {
is >> arg.value;
arg.check_value();
return is;
}
friend std::ostream &operator<<(std::ostream &os, foo_or_bar const &arg) {
return os << arg.value;
}
};
// test
void test(int argc, const char **argv) {
foo_or_bar my_foo;
po::options_description desc("test options");
desc.add_options()
(foo_or_bar::option_name(), po::value(&my_foo), foo_or_bar::description());
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
std::cout << "foo is " << my_foo << std::endl;
}
void print_exception(const std::exception& e, int level = 0)
{
std::cerr << std::string(level, ' ') << "exception: " << e.what() << '\n';
try {
std::rethrow_if_nested(e);
} catch(const std::exception& e) {
print_exception(e, level+1);
} catch(...) {}
}
int main() {
{
std::vector<const char *> test_args = {
"executable_name",
"--foo=bar"
};
test(test_args.size(), test_args.data());
}
try {
std::vector<const char *> test_args = {
"executable_name",
"--foo=bob"
};
test(test_args.size(), test_args.data());
}
catch (std::exception const &e) {
print_exception(e);
}
}
预期产出:
foo is bar
exception: the argument for option '--foo' is invalid
exception: value must be foo or bar, you supplied "bob"