Ошибка неизвестного имени типа при вставке в unordered_map

#c #compiler-errors #unordered-map

Вопрос:

У меня есть один файл под названием main.cpp где я пытаюсь объявить unordered_map , как показано ниже.

 std::unordered_maplt;std::string, std::setlt;intgt;gt; firstSets;  

Затем я пытаюсь вставить новую пару (ключ, значение) в карту следующим образом.

 std::string decl = "decl"; std::setlt;intgt; declFirstSet = {VOID_TOK, INT_TOK, FLOAT_TOK, BOOL_TOK}; firstSets[decl] = declFirstSet;  

Когда я это делаю, я получаю следующую ошибку компилятора.

C требует спецификатора типа для всех объявлений

Первые наборы[decl] = Первый набор;

размер массива имеет нецелочисленный тип ‘std::string’ (он же ‘basic_string’)

Первые наборы[decl] = Первый набор;

Так что, похоже, я думаю, что объявляю «Первые наборы», когда на самом деле пытаюсь вставить в него. И, похоже, он рассматривает «Первые наборы» как массив вместо an unordered_map . Как мне это исправить?

Комментарии:

1. Являются ли эти объявления/выражения глобальными (вне функции)?

2. Да. @1201программаларм

3. Поместите вставку внутрь main, и она должна работать

4. У вас не может быть выражений в глобальной области. firstSets[decl] = declFirstSet; должно быть внутри функции. Вы также можете инициализировать его с помощью конструктора при его определении.

5. хорошо, это сработало, спасибо. Почему у вас не может быть выражений в глобальном масштабе?

Ответ №1:

Ты std::make_pair ошибаешься. Чтобы подойти ближе, вам нужен а std::setlt;intgt; вместо std::set в.

Но чего вы действительно хотите, так это просто позволить компилятору сделать это за вас:

 firstSets.insert(std::make_pair(decl, declFirstSet));  

или используйте более простой синтаксис:

 firstSets[decl] = declFirstSet;  

ОТРЕДАКТИРУЙТЕ ПОСЛЕ ПОНИМАНИЯ ПРОБЛЕМЫ С другой стороны, вы хотите firstSets иметь начальный контент, вы можете изменить порядок объявлений:

 #include lt;setgt; #include lt;stringgt; #include lt;unordered_mapgt;  std::string decl{"decl"}; std::setlt;intgt; declFirstSet{1, 2, 3, 4}; std::unordered_maplt;std::string, std::setlt;intgt;gt; firstSets{{decl, declFirstSet}};  int main() {}  

Комментарии:

1. Я отредактировал свой вопрос, чтобы отразить предложенные вами изменения. @Бо Р

2. Мой тест вашего кода выглядит так #include lt;setgt; #include lt;stringgt; #include lt;unordered_mapgt; int main() { std::unordered_maplt;std::string, std::setlt;intgt;gt; firstSets; std::string decl = "decl"; std::setlt;intgt; declFirstSet = {1, 2, 3, 4}; firstSets[decl] = declFirstSet; } , поскольку вы не показываете весь код, проблема, скорее всего, ранее в исходном коде макросов, включающих VOID_TOK и другие значения, или в отсутствующем заголовке. Трудно сказать.

3. Мой код находится не в основной функции, а в глобальной области. Я обновлю, чтобы показать более подробный код. @Бо Р

4. @TomFinet, я знаю, что понимаю проблему. Вы не можете иметь выражение в области вне функции. Таким образом firstSets[decl] = declFirstSet; , компилятор пытается использовать это как объявление (которым оно не является). Иметь void somefunctionname() { firstSets[decl] = declFirstSet; } — это лучшее, что ты можешь сделать.

5. Синтаксис «проще» имеет другую семантику. Это может привести к незаметным ошибкам, если он думает, что они делают точно то же самое…

Ответ №2:

Я не знаю, почему это не работает, но вам не нужно вызывать make_pair… Изменение строки вставки на:

 firstSets.insert({decl, declFirstSet});  

Это должно решить вашу проблему.

Вот полный пример кода:

 #include lt;setgt; #includelt;stringgt; #include lt;unordered_mapgt; using namespace std; int main() {  std::unordered_maplt;std::string, std::setlt;intgt;gt; firstSets;  setlt;intgt; s = { 1, 2, 3 };  firstSets.insert({ "key", s });  }   

Но, похоже, вы хотите, чтобы они были объявлены в глобальной области, поэтому вы инициализируете их следующим кодом:

 #include lt;setgt; #includelt;stringgt; #include lt;unordered_mapgt; using namespace std;  setlt;intgt; s1 = { 1, 2, 3 }, s2 = { 4, 5, 6 }; std::unordered_maplt;std::string, std::setlt;intgt;gt; firstSets{ {"key1", s1}, {"key2", s2}}; int main() { }   

Комментарии:

1. Ошибка по-прежнему сохраняется. В нем по-прежнему говорится: «неизвестное имя типа «firstSets» «и»невозможно использовать оператор точки для типа». @vmp

2. @vmp, вы должны включить lt;stringgt; в свой пример.

3. о, да… visual studio, похоже, добавит его под капот, исправит это!