c ++/boost program_options一个选项禁用其他 [英] c++/boost program_options one option disable other

查看:126
本文介绍了c ++/boost program_options一个选项禁用其他的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的代码:

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,因为 从语义上来说,这是完全不同的事情.

and my program can work only either in mode1 or mode2. and I don't want syntax like this --mode 0/1, because of semantically this is completely different things.

因此可以告诉boost program_options 实现这种语义的模块

So it will be possible to tell boost program_options module to implement such semantic

无选项->错误

mode1->确定

mode2->确定

mode1 mode2->错误

mode1 mode2 -> error

?

注意:是的,我可以使用var_map.count并检查我自己 在po::notify之后,但我看到类似这样的类 http://www.boost.org/doc/libs/1_59_0/doc/html/boost/program_options/value_semantic.html 在文档中,我想知道我是否可以使用program_options中的内容来检查这种语义.

Note: yes, I can use var_map.count and check this my self after po::notify, but I see classes like these http://www.boost.org/doc/libs/1_59_0/doc/html/boost/program_options/value_semantic.html in documentation, and I wonder can I use something from program_options to check such semantic.

推荐答案

注意:是的,我可以使用var_map.count并在po :: notify之后检查我的自我,但是我在文档中看到了类似于value_semantic的类,我想知道我是否可以使用program_options中的内容来检查这种语义.

Note: yes, I can use var_map.count and check this my self after po::notify, but I see classes like these value_semantic in documentation, and I wonder can I use something from program_options to check such semantic.

嗯.您只能做很多事情;

Mmm. Only so much you can do;

您可以使用值语义在通知期间执行此操作:

You can use value-semantics to do this during notify:

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"}; }))
    ;

这仍然需要您验证是否分别指定了两种模式:

This still requires you to validate that either mode is specified separately:

if (!(mode1 || mode2))
    throw po::error("Mode must be specified");

查看 在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:

Manual validation

You could do without the notifiers above and simple write the constraint as a NXOR:

if (mode1 == mode2)
    throw po::error("Exactly 1 of --mode1 and --mode2 must be specified");

查看 在Coliru上直播

您当然可以使所有选项都产生自定义类型,并使通知者了解逻辑.

You could of course have all options result in a custom type and make the notifiers aware of the logic.

我将尝试演示它.更新:这是一个死胡同,因为所有值的语义都包含一个(可选)参数.这至少使事情变得难看.

I'll try to demo this. Update: This is a dead end since all value semantics imply an (optional) argument. This at the very least makes things ugly.

我当时正在思考: 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, ""))
        ;

如您所见,事情并没有完全按照我希望他们的方式进行

As you can see, things don't quite work out the way I'd like them to

这篇关于c ++/boost program_options一个选项禁用其他的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆