Reputation: 2611
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.
Upvotes: 0
Views: 7080
Reputation: 79921
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):
Qualify your variable declarations with std::
std::map<string, int> map;
std::map<string, int>::iterator iter = map.begin();
Drop the using namespace std;
and qualify everything with std::
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.
Upvotes: 11
Reputation: 208353
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.
Upvotes: 3
Reputation: 3587
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.
Upvotes: 6
Reputation: 5601
Try to change variable name from 'map' to 'm', maybe it will help.
Upvotes: 0