C ++ / boost program_options one parameter disable others

I have a code like this:

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

and my program can only work in mode1 or mode2. and I don’t want the syntax of type --mode 0/1, because semantically these are completely different things.

So, we can say the boost program_options module for implementing such a semantic

no option → error

mode1 → ok

mode2 → ok

mode1 mode2 → error

?

Note: yes, I can use var_map.countand check it myself 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 the documentation , and I wonder if I can use something from program_options to test such semantics.

+4
1

: , var_map.count po:: notify, , this value_semantic, , , - program_options .

. ;

value-semantics :

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

, .

. Update: , () . , , .

: 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, ""))
        ;

, , ,

+6

Source: https://habr.com/ru/post/1615823/


All Articles