【发布时间】:2017-07-30 14:58:46
【问题描述】:
boost::program_options 似乎支持某种程度的custom validation,但我觉得奇怪的是,验证是根据类型而不是按参数编写的,我想知道我是否在这里遗漏了什么。
例如,假设您有一个“文件编辑”程序,它从命令行获取 input 和 output 文件名。接下来假设您要将这些存储到boost::filesystem::path 类型的变量中。现在,假设我们要求input 文件必须 存在,但output 文件不存在(即如果output 文件不存在,我们将创建它。)理想情况下,我们有一种方法来测试input 参数是否存在,以及output 文件是否存在并且是可写的,或者位于我们可以写入的目录中。 (这里的具体差异实际上并不相关。这适用于您在多个地方使用相同类型的任何情况,您希望根据使用情况有不同的验证规则。)
因为我们通过创建 validate 的覆盖来配置验证器(可能在编译时通过它们的类型签名找到,看来我们只能为 boost::filesystem::path 的所有实例设置一个验证器。我见过 @987654333 @hook,但是这些回调的签名具有 const 限定符,因此您似乎无法修改该值,并且在文档中尚不清楚 throwing 在 notify 回调中如何工作进入验证系统。
这似乎是一个非常基本的限制,以至于我认为我可能遗漏了一些东西。我是吗?想法?
【问题讨论】:
-
你可以将你的参数包装成它自己的类型。
-
这比听起来要难。例如, boost::filesystem::path 有许多构造函数可以手动为其编写传递。我尝试使用 C++11 构造函数继承,但该功能与 boost::program_options 中的各种元编程之间似乎存在一些根本的不兼容。抽象地说,将有效的特定于上下文的运行时复杂性(即我使用
program_options的复杂性,而不是它的功能)强加到类型系统上也是错误的。 -
除了默认的,不需要实现构造函数。包装器类型仅用于进行转换,不应在参数处理代码之外使用(外部代码应接收基类型)。