#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, похоже, добавит его под капот, исправит это!