Есть ли std :: mapв C ++ поддерживают родные типы данных, такие как структуры? - PullRequest
0 голосов
/ 30 сентября 2010

Как мне сопоставить ключ с собственным типом данных, таким как структура?

Я написал этот фрагмент кода, но не смог его скомпилировать.У вас есть идеи, как это исправить?

#include <map>
#include <iostream>

typedef struct _list
{
  int a,b;
}list;
map<int,list> test_map;

int main(void)
{
  cout <<"Testing"<< endl;
}

Ответы [ 6 ]

4 голосов
/ 30 сентября 2010

карта находится в пространстве имен std ::.Два возможных способа исправить это:

using namespace std;
// ...
map<int, list> test_map;

или

std::map<int, list> test_map;

Я предпочитаю второй метод, но это сугубо личный выбор.

В связанной заметке,нет никаких реальных ограничений на то, что вы можете поместить в карту, кроме того факта, что они должны быть копируемыми / назначаемыми, и что тип ключа должен иметь оператор <(или вы также можете предоставить функтор сравнения). </p>

РЕДАКТИРОВАТЬ: Похоже, <list> где-то включен, либо в <iostream> (маловероятно) или <map> (странно, но не невозможно).Использование пространства имен std приведет к конфликту std :: list с вашей собственной структурой.Решение: переименуйте вашу структуру или удалите используемое пространство имен и поместите std :: там, где это необходимо.

2 голосов
/ 30 сентября 2010

Добавлено std, где требуется.

Переименован список в mylist, чтобы избежать конфликта с std::list.Избегайте совпадений с именами переменных и именами, которые часто встречаются.

Теперь компилируется нормально в VS2008.

#include <map>
#include <iostream>

typedef struct _list
{
    int a,b;
} mylist;

std::map<int,mylist> test_map;

int main(void)
{
    std::cout <<"Testing"<< std::endl;
    return 0;
}

Нет проблем с использованием вашей структуры в контейнерах STL, если она полностью копируема (конструктор копирования), присваиваемый (реализует operator=) и сопоставимый (реализует operator<).

1 голос
/ 30 сентября 2010

Ряд проблем здесь:

  • Вам не хватает using::std или std::map, поэтому компилятор не знает, что означает map<int,list>.

  • Если у вас есть объявление using namespace std, ваш typedef list может столкнуться с коллекцией STL с тем же именем. Измените имя.

  • Ваша конструкция typedef struct _tag {...} tag; является архаичным пережитком 80-х годов. Это не обязательно, и, честно говоря, довольно глупо. Это ничего не дает.

Вот ваш исправленный код:

#include <map>
#include <iostream>

struct MyList
{
  int a,b;
};

std::map<int,MyList> test_map;

int main(void)
{
  std::cout <<"Testing"<< std::endl;
  return 0;
}
0 голосов
/ 30 сентября 2010

Я бы постарался вообще не использовать кодовую панель.

Я провел пару тестов с вашим кодом, и кажется, что

  • это добавление неявного (и нежелательного) using namespace std - это не требует от вас квалификации map, cout или endl.
  • (вероятно) включает в себя больше стандартных заголовков, чем вы могли бы хотеть, включая #include <list>.

Это означает, что когда компилятор смотрит на код, он видит две list, вашу версию и одну в std. Из-за директивы using оба находятся в области видимости в строке, где вы создаете карту, и компилятор не может определить, какой из них использовать.

Две простые вещи, которые вы можете сделать: измените имя вашего типа для простого теста на что-то отличное от list (оу! Инструмент, заставляющий ваш выбор имен!) Или полностью определите использование:

#include <map>
struct list {
   int a,b;
};
std::map< int, ::list > the_map;
// ...

Обратите внимание, что codepad добавляет включение сам по себе и директиву using, поэтому он также скомпилирует:

struct list {
   int a,b;
};
map<int,::list> the_map;

Но этот кусок кода неправильный

0 голосов
/ 30 сентября 2010

map<int, _list> test_map; или не используйте list (намного лучше) в качестве имени структуры. (Возможно, у вас также есть

#include <list>
...
using namespace std;

где-то в вашем коде.

0 голосов
/ 30 сентября 2010

Вы, кажется, пришли от C. Попробуйте это:

#include <map>
#include <iostream>

struct list
{
  int a,b;
};

std::map<int,list> test_map;

int main(void)
{
  std::cout <<"Testing"<< std::endl;
  return 0;
}
...