5

I'm having trouble understanding an error. I'm working with a straightforward map of vectors (keyed by strings and storing vectors of strings):

typedef std::map<std::string, std::vector<std::string> > TRouteMarkets;

The following code (stripped down),

void CFoo::Bar(const char* route, const char* market)
{
    // ...

    TRouteMarkets::key_type key(route);
    TRouteMarkets::mapped_type mapped();
    TRouteMarkets::value_type pair(key, mapped);

    // ...
}

produces the following error:

"Foo.cc", line 518: Error: Could not find a match for std::pair<const std::string, std::vector<std::string>>::pair(const std::string, std::vector<std::string>()) needed in CFoo::Bar(const char*, const char*).

But removing the () from mapped, i.e.

TRouteMarkets::mapped_type mapped;

fixes the error. Why? Isn't mapped an empty vector of strings in either case?

Andrew Cheong
  • 29,362
  • 15
  • 90
  • 145
  • 4
    Read about [the most vexing parse](http://en.wikipedia.org/wiki/Most_vexing_parse). – Some programmer dude Apr 26 '13 at 14:37
  • We really need an automatic checker for the vexing parse and family. I had a good idea from the question title what this would be, it comes up so often (c: – Peter Wood Apr 26 '13 at 14:49
  • 3
    This is not the most vexing parse. – hmjd Apr 26 '13 at 14:50
  • @hmjd - Could you elaborate, perhaps by editing your answer? I'm curious to know the distinction between what I'm reading on Wikipedia, and my code. – Andrew Cheong Apr 26 '13 at 14:53
  • @ecatmur - I'd delete the question, but I guess it might still be useful as a search result for those, like me, who might think the problem has something to do with initializing an empty vector. – Andrew Cheong Apr 26 '13 at 15:41

2 Answers2

7

This is actually a function declaration:

TRouteMarkets::mapped_type mapped();

declaring a function named mapped that accepts no arguments and returns a TRouteMarkets::mapped_type.

hmjd
  • 120,187
  • 20
  • 207
  • 252
5

You've run into the Most Vexing Parse problem.

TRouteMarkets::mapped_type mapped();

The above line is declaring a function named mapped that takes no arguments and returns an object of type TRouteMarkets::mapped_type.

With C++11, you can use uniform initialization syntax to avoid this problem.

TRouteMarkets::mapped_type mapped{}; // Not a function declaration anymore
Praetorian
  • 106,671
  • 19
  • 240
  • 328
  • Ah, all is clear again; can't believe I've never run into this issue before! Thank you, and apologies to @hmjd and @@JoachimPileborg that only one can be awarded for the answer. – Andrew Cheong Apr 26 '13 at 14:51
  • 3
    This is not the most vexing parse. – hmjd Apr 26 '13 at 14:52
  • 3
    The most vexing parse is even more vexing. – juanchopanza Apr 26 '13 at 15:04
  • @Praetorian, because it is just a function declaration. The most vexing parse has an argument, treated as an unamed function. Check the article linked in your answer and any article you can find on it. – hmjd Apr 26 '13 at 15:05
  • @hmjd Isn't this just a simplified case of that? The phrase *most vexing parse* describes a syntactic ambiguity, which is what this is. – Praetorian Apr 26 '13 at 15:08
  • 2
    @Praetorian, I don't think so. Vexing yes, but not most vexing. :) – hmjd Apr 26 '13 at 15:11
  • 'The most vexing parse' as coined by Meyers refers specifically to a version of this with a non-empty initializer, not just any syntactic ambiguity between variable and function declarations. – bames53 Apr 26 '13 at 15:32