Проблема итератора карты C ++ - PullRequest
0 голосов
/ 01 марта 2011

почему этот код проблематичен (в 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 ]

11 голосов
/ 01 марта 2011

Вы назвали свою переменную 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. Переименуйте переменную map.Действительно, вам, вероятно, следует избегать использования имен, определенных библиотекой, для имен переменных.

edit: Ответ Марка также должен работать для вас.

6 голосов
/ 01 марта 2011

Хммм, интересно, если бы компилятор был доволен:

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

Я бы в любом случае стремился к этому, так как он уменьшает DRY и выглядит для меня чище.

Также имя переменной map может сбивать с толку компилятор, и, по крайней мере, может запутать человека, читающего код, поэтому я бы изменил это.

3 голосов
/ 01 марта 2011

Проблема в том, что вы определяете map как переменную внутри main.Само определение вроде в порядке, так как, когда тип анализируется, переменная еще не была объявлена, и map в map<string, int> ищется с общими правилами поиска, сначала внутри функции,затем во вложенном пространстве имен, а затем в используемом пространстве имен (std) из-за строки using namespace std;.

После того, как переменная определена в первой строке в main, идентификатор map относится клокальная переменная.По сути, компилятор видит map в map<string,int>::iterator и ищет его.Он находит локальное имя map, которое ссылается на переменную, и останавливает поиск там.Затем он видит следующий токен препроцессора < и анализирует его как оператор меньше чем , затем находит 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();
}

, и выбор более разумных имен для переменных может помочь избежать подобных проблем.

0 голосов
/ 01 марта 2011

Попробуйте изменить имя переменной с 'map' на 'm', возможно, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...