c++ - boost::program_options :迭代并打印所有选项

标签 c++ boost command-line boost-program-options

我最近开始使用boost::program_options并发现它非常方便。也就是说,缺少一件事我无法以一种好的方式编写自己的代码:

我想遍历 boost::program_options::variables_map 中收集的所有选项将它们输出到屏幕上。这应该成为一个方便的函数,我可以简单地调用它来列出所有设置的选项,而无需在添加新选项或每个程序时更新函数。

我知道我可以检查和输出单个选项,但如上所述,这应该成为一个忽略实际选项的通用解决方案。我进一步知道我可以遍历 variables_map 的内容因为它只是一个扩展的 std::map .然后我可以检查存储的 boost::any 中包含的类型。变量和使用.as<>将其转换回适当的类型。但这意味着要编写一个长开关 block ,每种类型都有一个案例。这对我来说看起来不是很好的编码风格。

所以问题是,有没有更好的方法来迭代这些选项并输出它们?

最佳答案

正如@Rost 之前提到的,访问者模式在这里是一个不错的选择。要将它与 PO 一起使用,您需要为您的选项使用通知程序,这样如果通过了选项,通知程序将填写您的集合中的一个条目 boost::variant值(value)观。该套装应单独存放。之后,您可以使用 boost::apply_visitor 遍历您的集合并自动处理对它们的操作(即打印)。 .

对于访问者,继承自 boost::static_visitor<>

实际上,我使访问者和通用方法的使用范围更广。

我创建了一个 class MyOption包含描述,boost::variant用于 value 和其他选项,如隐式、默认等。我填充了 MyOption 类型的对象 vector 就像 PO 通过模板为他们的选项做的一样(见 boost::po::options_add() )。在逝去的瞬间std::string()double()对于 boosts::varian t 初始化您填充值的类型和其他内容,如默认、隐式。

之后我使用访问者模式填充 boost::po::options_description容器自 boost::po需要自己的结构来解析输入命令行。在填充过程中,我为每个选项设置了通知器 - 如果它会通过 boost::po将自动填充我的原始对象 MyOption .

接下来需要执行po::parsepo::notify .之后,您将可以使用已填写的 std::vector<MyOption*>通过访问者模式,因为它在内部包含 boost::variant。

这一切有什么好处 - 您只需在代码中编写一次选项类型 - 在填写 std::vector<MyOption*> 时.

PS。如果使用此方法,您将面临为没有值的选项设置通知器的问题,请参阅此主题以获得解决方案:boost-program-options: notifier for options with no value

PS2。代码示例:

std::vector<MyOptionDef> options;
OptionsEasyAdd(options)
  ("opt1", double(), "description1")
  ("opt2", std::string(), "description2")
...
;
po::options_descripton boost_descriptions;
AddDescriptionAndNotifyerForBoostVisitor add_decr_visitor(boost_descriptions);
// here all notifiers will be set automatically for correct work with each options' value type
for_each(options.begin(), options.end(), boost::apply_visitor(add_descr_visitor));  

关于c++ - boost::program_options :迭代并打印所有选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12244289/

相关文章:

c++ - 如何在不同的命名空间中指定重载运算符?

c++ - 当你想实现一个可以返回 "nothing"的函数时,何时使用 boost::optional 以及何时使用 std::unique_ptr ?

c++ - OpenCV:为什么 *p_img1=*p_img2 不正确

c++ - 为什么 ucontext 有这么高的开销?

c++ - boost::program_options 和位置参数的问题

Linux:查找链接到特定目录的所有软链接(soft link)

c++ - 无法在 MFC 中的 CFile 中设置只读属性?

c++ - boost asio tcp socket 1.70 不向后兼容

Windows 命令行 - 将文件修改时间戳更改为较早的日期时间

command-line - 处理多个文件名的 Unix 脚本