1

I wrote this quick function to get familiar with boost::program_options. Please note that po is a namespace alias, defined thus: namespace po = boost::program_options.

int application(po::variables_map* vm)
{
    std::cout << vm << std::endl;
    std::cout << *vm["infile"].value();
    // also tried:  std::cout << *vm["infile"]

    return SUCCESS;
}  //application

When I comment out the second line in the function body, the application successfully compiles and prints the address of vm. However, when I try to compile with the function appearing as it does here, I get the following compiler insult:

invalid types ‘boost::program_options::variables_map*[const char [7]]’ for array subscript

I should note that replacing the second line with std::cout << vm->count("infile") returns 1.

What have I done wrong? Am I abusing a boost construct or am I getting mixed up in (de)referencing vm?

Update

Following the suggestion that I pass by reference to avoid the operator precedence issue, I rewrote my function thus:

int application(po::variables_map& vm)
{
    std::cout << &vm << std::endl;
    std::cout << vm["infile"].value();

    return SUCCESS;
}  //application

I'm now getting a different error:

no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream<char>}’ and ‘const boost::program_options::variable_value’)

What have I done wrong here?

Edit: I'd appreciate being told why my question is being downvoted. Is it too basic?

Louis Thibault
  • 20,240
  • 25
  • 83
  • 152
  • 4
    http://en.cppreference.com/w/cpp/language/operator_precedence – chris May 18 '13 at 17:53
  • 1
    Just a wild guess, try this `(*vm)["infile"]`. – masoud May 18 '13 at 17:53
  • Something worth memorizing: `[]` has higher precedence than `*` and `p->x` is sugar for `(*p).x` (more or less) – Ray Toal May 18 '13 at 17:54
  • 1
    Although `(*vm).["infile"]` will probably work, you're probably better off eliminating the problem -- pass `vm` by reference instead of passing a pointer. – Jerry Coffin May 18 '13 at 17:55
  • @RayToal, ah, yikes! That's indeed very good to know! It all makes sense now... My compiler is trying to dereference the result of `[]` on the pointer, correct? – Louis Thibault May 18 '13 at 17:59
  • @JerryCoffin, duly noted! I can't quite understand why a `.` is required, though. Could you give me a hint? – Louis Thibault May 18 '13 at 18:00
  • Yes, the meaning of `*vm["infile"]` is `*(vm["infile"]). The cool thing is that `*` and `[]` are just regular operators and you can use parentheses anywhere in the expression to make yourself very clear. I tend to always use them when mixing `*` and `[]`. – Ray Toal May 18 '13 at 18:01
  • @blz: In general, postfix operators have higher precedence than prefix ones. – AnT stands with Russia May 18 '13 at 18:11
  • @blz: That would have very little to do with the language, and a lot to do with my (lack of) typing skill. – Jerry Coffin May 18 '13 at 22:23

1 Answers1

6

The [] operator has a higher precedence than the unary * operator. Thus, *vm["infile"] is the same as *(vm["infile"]), but you want (*vm)["infile"].

Oswald
  • 31,254
  • 3
  • 43
  • 68
  • thank you for your answer! I tried rewriting this to pass-by-reference (as suggested by JerryCoffin). I'm now getting an entirely different error. Do you have any suggestions? – Louis Thibault May 18 '13 at 18:12