C ++映射迭代器问题

时间:2011-03-01 19:04:04

标签: c++ iterator

为什么这段代码有问题(在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();
}

它只是告诉我迭代器定义中存在问题(类模板“std :: iterator”的参数列表丢失),但是我看到了这样写的样本。

4 个答案:

答案 0 :(得分:11)

您调用了变量map并使用了using namespace std;,这会导致名称查找问题,因为您使用的变量和库容器名称相同。大卫在评论和下面的内容中解释了这一部分。

你可以做几件事(除了这些之外你还可以做更多的事情):

  1. 使用std::

    对变量声明进行限定

    std::map<string, int> map;

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

  2. 放弃using namespace std;并使用std::

  3. 限定所有内容
  4. 重命名map变量。实际上,您应该避免使用库定义的名称作为变量名。
  5. 编辑:Marc's answer也适用于您。

答案 1 :(得分:6)

嗯,我想知道编译器是否满意:

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

无论如何,我会倾向于这一点,因为它会减少DRY并使我看起来更清洁。

变量名map也可能让编译器感到困惑,至少可能会让读者感到困惑,所以我会改变它。

答案 2 :(得分:3)

问题在于您将map定义为main内的变量。定义本身是好的,因为在解析类型时尚未声明变量,并且使用公共查找规则查找map中的map<string, int>,首先在函数内部,然后在封闭的命名空间中,然后在使用的命名空间(std)中由于using namespace std;行。

在main的第一行中定义变量后,标识符map引用局部变量。编译器基本上会在map中看到map<string,int>::iterator并进行查找。它找到引用变量的本地名称map并在那里停止查找。然后它会看到下一个预处理程序令牌<并将其解析为 less-than 运算符,然后找到string并且它会阻止一些错误消息。

您应该始终记住,对于非限定名称的C ++查找在内部上下文中开始并从那里爬出,但它将在您使用的第一次出现的标识符时停止。您可以通过明确限定标识符来解决这个问题,这也可以解决问题。请注意,对于以该语言开头的人来说,using namespace可能不是一个好的提示。

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

在此修改后的版本中,通过在std::之前添加资格map,您暗示编译器您不希望在当前上下文中使用map变量,而是来自map命名空间的std标识符。如果你完全删除using会更好:

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

为变量选择更合理的名称可能有助于避免此类问题。

答案 3 :(得分:0)

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