c++ - boost::program_options 验证每个参数而不是每个参数类型?

标签 c++ boost-program-options

boost::program_options 似乎支持某种级别的 custom validation但对我来说,验证是根据类型而不是每个参数编写的,这似乎很奇怪,我想知道我是否在这里遗漏了什么。

例如,假设您有一个“文件编辑”程序,它从命令行获取inputoutput 文件名。接下来假设您要将这些存储到 boost::filesystem::path 类型的变量中。现在,假设我们要求 input 文件必须存在,但 output 文件不存在(即如果 output 文件不存在,我们将创建它。)理想情况下,我们有一种方法可以测试 input 参数是否存在,以及 output 文件存在且可写,或者位于我们可以写入的目录中。 (这里的具体差异实际上并不相关。这适用于您在多个地方使用相同类型的任何情况,您希望根据用途使用不同的验证规则。)

因为我们通过创建 validate 的覆盖来配置验证器(这大概是在编译时通过它们的类型签名找到的,看来我们只能为 boost::的所有实例设置一个验证器: filesystem::path。我看到了 notify 钩子(Hook),但是那些回调的签名有一个 const 限定符,所以它看起来不像你可以修改该值,并且在文档中不清楚 thrownotify 回调中如何在验证系统中工作。

这似乎是一个非常基本的限制,我认为我可能遗漏了一些东西。我是吗?想法?

最佳答案

在程序中为每个概念使用一种类型永远不会有坏处。如果两条路径代表不同的概念,则给它们自己的类型:

#include <iostream>
#include <cstdlib>
#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>

namespace po = boost::program_options;
namespace fs = boost::filesystem;

template<class Type, class Tag>
struct tagged
{
    Type const& get() const { return value_; }
    Type& get() { return value_; }
    operator Type& () { get(); }

    friend decltype(auto) operator>>(std::istream& is, tagged& t) {
        return is >> t.get();
    }

    friend decltype(auto) operator<<(std::ostream& os, tagged const& t) {
        return os << t.get();
    }

    // and so on...

    Type value_;
};

using bar_path = tagged<fs::path, class bar_path_tag>;
using foo_path = tagged<fs::path, class foo_path_tag>;

int main()
{
    bar_path bar;
    foo_path foo;

    po::options_description desc("prog");
    desc.add_options()
    ("foo", po::value(&foo), "a foo path")
    ("bar", po::value(&bar), "a bar path")
    ;
}

关于c++ - boost::program_options 验证每个参数而不是每个参数类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45401178/

相关文章:

c++ - 如何使用 CMake 在 macOS 上使用和链接 boost?

c++ - boost 程序选项 : linking error

c++ - 使用OpenCV C++绘制最大轮廓的凸包

c++ - 在函数结束后使用指向变量的指针是否安全?

c++ - Boost:位置参数无法识别的选项

c++ - 使用 vm.count() 时始终存在具有默认值的 Boost 程序选项

c++ - Boost.Program_options 没有参数默认行为?

c++ - C++ 语法的两个好奇心

c++ - 跟踪对 std::cout 的调用

c++ - 在模板类中使用嵌套的嵌套类时,“依赖名称不是类型”