c++/boost program_options 一个选项禁用其他
Posted
技术标签:
【中文标题】c++/boost program_options 一个选项禁用其他【英文标题】:c++/boost program_options one option disable other 【发布时间】:2015-11-13 20:20:49 【问题描述】:我有这样的代码:
namespace po = boost::program_options;
po::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("mode1", "")
("mode2", "");
po::variables_map var_map;
po::store(po::parse_command_line(argc, argv, desc), var_map);
po::notify(var_map);
而我的程序只能在模式 1 或模式 2 中运行。
我不想要像--mode 0/1
这样的语法,因为
从语义上讲,这是完全不同的事情。
所以可以告诉 boost program_options 实现这种语义的模块
没有选项 -> 错误
mode1 -> 好的
模式2 -> 好的
mode1 mode2 -> 错误
?
注意:是的,我可以使用 var_map.count
并自行检查
在po::notify
之后,但我看到类似http://www.boost.org/doc/libs/1_59_0/doc/html/boost/program_options/value_semantic.html 的课程
在文档中,我想知道我可以使用 program_options 中的一些东西来检查这种语义。
【问题讨论】:
在this example他们似乎使用var_map
的检查方法。
【参考方案1】:
注意:是的,我可以使用 var_map.count 并在 po::notify 之后自行检查,但我在文档中看到了类似 value_semantic 的类,我想知道我可以使用 program_options 中的一些东西来检查这种语义。
嗯。你能做的只有这么多;
自定义通知器
您可以在期间通知使用值语义来执行此操作:
po::options_description od;
od.add_options()
("mode1", po::bool_switch(&mode1)->notifier([&](bool b) if (b && mode2) throw po::error"Only one mode may be specified"; ))
("mode2", po::bool_switch(&mode2)->notifier([&](bool b) if (b && mode1) throw po::error"Only one mode may be specified"; ))
;
这仍然需要您验证是否单独指定了任一模式:
if (!(mode1 || mode2))
throw po::error("Mode must be specified");
看Live On Coliru
+ ./a.out
Mode must be specified
+ ./a.out --mode1
mode1: true mode2: false
+ ./a.out --mode2
mode1: false mode2: true
+ ./a.out --mode1 --mode2
Only one mode may be specified
+ ./a.out --mode2 --mode1
Only one mode may be specified
手动验证
您可以不使用上面的通知器,只需将约束写为 NXOR:
if (mode1 == mode2)
throw po::error("Exactly 1 of --mode1 and --mode2 must be specified");
看Live On Coliru
高科技
您当然可以让所有选项都生成自定义类型,并使通知器了解逻辑。
我将尝试对此进行演示。 更新:这是一个死胡同,因为所有值语义都暗示了一个(可选的)参数。这至少让事情变得丑陋。
我是这样想的:http://coliru.stacked-crooked.com/a/a7bd9072f3fa024e
enum class Mode
mode1 = 1,
mode2 = 2
;
using mode_select = boost::optional<Mode>;
mode_select mode;
po::options_description od;
od.add_options()
("mode1", po::value<mode_select>(&mode)->implicit_value(Mode::mode1, ""))
("mode2", po::value<mode_select>(&mode)->implicit_value(Mode::mode2, ""))
;
如您所见,事情并没有像我希望的那样发展
【讨论】:
非常感谢您提供如此详细的回答。以上是关于c++/boost program_options 一个选项禁用其他的主要内容,如果未能解决你的问题,请参考以下文章
使用 boost::program_options 打印普通和位置参数的帮助
boost::program_options - 解析多个命令行参数,其中一些是字符串,包括空格和字符
Boost.Program_Options:当 <bool> 被指定为命令行选项时,啥是有效的命令行参数?
未定义的引用`boost :: program_options :: options_description :: m_default_line_length'