简体   繁体   中英

C++ map iterator problem

why is this code problematic(in visual studio 2010)?

#include <iostream>
#include <fstream>
#include <string>
#include <map>

using namespace std;

int main() {

    map<string,int> map;
    map<string,int>::iterator iter = map.begin();
}

it just tells me there is a problem in the iterator definition(argument list for class template "std::iterator" is missing), but I saw samples written that way.

You called your variable map and you used using namespace std; which will result in name lookup issues as you are using a variable and a library container called the same thing. David in the comments and below explains that portion more.

You can do several things (and there are more you can do beyond these):

  1. Qualify your variable declarations with std::

    std::map<string, int> map;

    std::map<string, int>::iterator iter = map.begin();

  2. Drop the using namespace std; and qualify everything with std::

  3. Rename your map variable. Really, you should probably avoid using library defined names for your variable names.

edit: Marc's answer also should work for you as well.

Hmmm, I wonder if the compiler would be happy with:

typedef map<string,int> MapType;
MapType myMap;
MapType::iterator iter = myMap.begin();

I would gravitate towards this anyway as it reduces DRY and looks cleaner to me.

Also the variable name map might be confusing the compiler, and at the very least could confuse a human reading the code, so I would change that.

The problem is that you are defining map as a variable inside main . The definition itself is kind of ok, as when the type is parsed the variable has not yet been declared, and map in map<string, int> is looked up with the common lookup rules, first inside the function, then in the enclosing namespace, and then in the used namespace ( std ) due to the using namespace std; line.

After the variable is defined in the first line in main, the identifier map refers to the local variable. Basically the compiler sees map in map<string,int>::iterator and looks it up. It finds the local name map that refers to the variable and stops the lookup there. Then it sees the next preprocessor token < and parses it as a less-than operator, then it finds string and it barfs some error message.

You should always keep in mind that C++ lookup for unqualified names starts in the inner context and crawls out from there, but it will stop with the first occurrence of the identifier that you are using. You can solve that by explicitly qualifying identifiers, and that would also solve the issue. Note that using namespace is probably not a good hint for someone starting with the language.

using namespace std; // <- best remove this algothether
int main() {
   map<string, int> map;
   std::map<string, int>::iterator it = map.begin(); // [1]
}

In this modified version, by adding the qualification std:: before map you are hinting the compiler that you don't want the map variable in the current context but rather the map identifier from the std namespace. It would be better if you removed the using altogether:

int main() {
   std::map<std::string, int> map;
   std::map<std::string, int>::iterator it = map.begin();
}

And choosing more sensible names for variables might help in avoiding this type of problems.

尝试将变量名从“ map”更改为“ m”,也许会有所帮助。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM