1

The application has two options: a and file. file is a positional option. Both a and file have an argument of type string, which can be omitted. (I have set an implicit empty string for both).

The desired behaviour is as follows:

  1. $ program -> file: ""

  2. $ program file.txt -> file: "file.txt"

  3. $ program --a -> a: "", file: ""

  4. $ program --a file.txt -> a: "", file: "file.txt"

  5. $ program --a x file.txt -> a: "x", file: "file.txt"

However, option 4 is intepreted as a: "file.txt", file: "". Is there any way to inform program_options about how to resolve this ambiguous situation? ($ program --a -- file.txt does work as expected, but I would like to have this working without the extra -- as well.) I am using the empty string to indicate 'not specified' currently, but this is not a requirement.

Ruud
  • 3,118
  • 3
  • 39
  • 51

2 Answers2

0

I would say even user will be confused with such behavior, not just PO. I can't understand why I can't specify --a without file, especially if file has an implecit value? What is the purpose of an implicit empty filename for not obligate positional option? I can't think of one.

You could implement your logic by giving PO your parser, it is described in the documentation. Also, and the simplest, you could manually change arguments after parsing if file is not passed.

Riga
  • 2,099
  • 1
  • 19
  • 27
  • The `a` option alone operates on all entries by default, whereas the argument allows filtering. The `file` can either be specified explicitly, but if it is not, the program will read if from a configuration file. – Ruud Jul 22 '12 at 19:00
  • If `a` option value is logically sufficient, why you make it an implicit? Per your words you allow users to pass filter as "" (no information), but this makes no sense, I believe. If you disallow impilicit value for `a` your logic in (4) will be preserved. – Riga Jul 23 '12 at 10:03
  • Not setting an implicit empty string yields the same results. Please note, ideally, an empty string is a different value than 'not specified', I am using the empty string to represent 'not specified'. The filter "" is equal to not filtering at all. – Ruud Aug 01 '12 at 16:32
0

I solved the problem by manually moving the argument from a to file if a was specified like this:

// Fix argument precedence
if (!vm.count("file") && vm.count("a"))
{
    vm.insert(std::make_pair("file", vm.at("a")));
    vm.at("a").as<std::string>() = std::string();
}
Ruud
  • 3,118
  • 3
  • 39
  • 51