正如@Rost 之前提到的,访客模式在这里是一个不错的选择。要将它与 PO 一起使用,您需要为您的选项使用通知程序,这样如果通过了选项,通知程序将在您的boost::variant
值集中填充一个条目。该套装应单独存放。之后,您可以迭代您的集合并使用boost::apply_visitor
.
对于访客,继承自boost::static_visitor<>
实际上,我使访问者和通用方法的使用范围更广。
我创建了一个class MyOption
包含描述、boost::variant
值和其他选项(如隐式、默认等)的内容。MyOption
我用与 PO 一样的方式填充该类型对象的向量(参见boost::po::options_add()
参考资料)。在传递std::string()
或double()
为boosts::varian
t 初始化的那一刻,您填充值的类型和其他内容,如默认、隐式。
之后我使用访问者模式来填充boost::po::options_description
容器,因为boost::po
需要它自己的结构来解析输入命令行。在填充过程中,我为每个选项设置了 notifyer - 如果它通过boost::po
将自动填充我原来的MyOption
.
接下来你需要执行po::parse
and po::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));