【问题标题】:C++ map iterator problemC++映射迭代器问题
【发布时间】:2011-03-01 19:04:04
【问题描述】:

为什么这段代码有问题(在 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”的参数列表丢失),但我看到了这样写的示例。

【问题讨论】:

  • 您能否粘贴您收到的确切错误消息?
  • 可能是因为您使用map 作为变量名?

标签: c++ iterator


【解决方案1】:

您调用了变量map 并使用了using namespace std;,这将导致名称查找问题,因为您使用的变量和库容器名称相同。 cmets 和下面的 David 对此部分进行了更多解释。

您可以做几件事(除此之外,您还可以做更多事情):

  1. 使用std:: 限定您的变量声明

    std::map&lt;string, int&gt; map;

    std::map&lt;string, int&gt;::iterator iter = map.begin();

  2. 删除 using namespace std; 并使用 std:: 限定所有内容

  3. 重命名您的map 变量。确实,您应该避免使用库定义的名称作为变量名。

编辑:Marc's answer 也应该适合你。

【讨论】:

  • 技术上std::map 不在全局命名空间中,而是查找算法会将std 命名空间添加到搜索集 处理全局命名空间之后。如果同一标识符出现在多个命名空间中,则差异最为显着:namespace A { void foo( int ) {} } namespace B { using namespace A; void foo( double ) {} } int main() { using namespace B; foo( 1 ); } 将调用 B::foo( double ) 而不是 A::foo( int ),即使后者更好匹配。
【解决方案2】:

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

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

无论如何我都会倾向于这个,因为它减少了DRY 并且对我来说看起来更干净。

另外,变量名map 可能会混淆编译器,至少可能会混淆阅读代码的人,所以我会改变它。

【讨论】:

  • +1 我喜欢这个答案,而且将这样的声明隐藏在更好的 typedef 后面总是很好。
【解决方案3】:

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

在main的第一行定义变量后,标识符map指的是局部变量。基本上,编译器在map&lt;string,int&gt;::iterator 中看到map 并进行查找。它找到引用该变量的本地名称map 并在那里停止查找。然后它会看到下一个预处理器标记 &lt; 并将其解析为 小于 运算符,然后找到 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]
}

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

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

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-15
      • 2011-07-31
      • 1970-01-01
      • 2011-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多