Карта STL, содержащая ссылки, не компилируется - PullRequest
8 голосов
/ 29 мая 2010

следующее:

std::map<int, ClassA &> test;

дает:

error C2101: '&' on constant

Пока следующее

std::map<ClassA &, int> test;

1010 * дает *

error C2528: '_First' : pointer to reference is illegal

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

Ответы [ 3 ]

16 голосов
/ 29 мая 2010

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

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

Если ваш тип маленький, вы можете скопировать его на карту или, если он большой, подумайте об использовании указателей вместо этого, но помните, что контейнер не будет освобождать объекты для вас, вам придется делать это явно самостоятельно.

Этот ТАК вопрос может вас заинтересовать.

3 голосов
/ 29 мая 2010

§8.3.2 раздел 5

Не должно быть ссылок на ссылки, массивов ссылок и указателей на ссылки.

Вы, вероятно, думаете о ссылках как о забавных указателях. Это не так.

1 голос
/ 29 мая 2010

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

Однако вы можете эмулировать поведение, используя указатель:

std::map<int, ClassA*> test;

Это немного раздражает, потому что вам нужно разыменовать дважды:

std::map<int, ClassA*>::iterator it = test.begin();

it->second->foo();

, но с map это гораздо менее запутанно, чем с vector или set (это будет (*it)->foo().

Наконец, есть несколько ошибок (указателей):

  • Вы должны убедиться, что указанный объект останется живым, пока вы хотите использовать указатель
  • Инициализация указателя по умолчанию является случайным значением, использование которого вызывает неопределенное поведение
  • Когда указатель отбрасывается, объект остается (к счастью), но это означает, что вам нужно, чтобы он был уничтожен в одной точке
...