В чем разница между двумя строками?
map<int, float> map_data;
map<const int, float> map_data;
В чем разница между двумя строками?
map<int, float> map_data;
map<const int, float> map_data;
int
и const int
- два разных типа.
std::map<int, float>
и std::map<const int, float>
также аналогичны различным типам.
Разница между std::map<const int, float>
и std::map<int, float>
в некоторой степени аналогична разнице между, скажем, std::map<int, float>
и std::map<std::string, float>
; вы получаете новый тип карты для каждого.
В случае с не-t28 > внутренний тип ключа по-прежнему не const
int
:
std::map<const int, float>::key_type => const int
std::map<int, float>::key_type => int
Однако ключи карты семантически неизменяемы, и все операции с картами, которые обеспечивают прямой доступ к клавишам (например, именования разыменования, которые дают value_type
), имеют const
ify key_type
:
std::map<const int, float>::value_type => std::pair<const int, float>
std::map<int, float>::value_type => std::pair<const int, float>
Таким образом, разница может быть в значительной степени невидима для вас во всех отношениях, если это позволяет ваша реализация.
Это не всегда так: стандарт официально требует, чтобы ваш тип ключа был возможностью для копирования и перемещения, а некоторые реализации повторно использовали узлы карт; в этих реализациях попытка использовать ключ const
просто не будет работать.
Как упоминалось в комментариях, разница между между двумя строками. Например, если вы пишете функцию, которая принимает map<const int, int>
, вы не можете передать ей map<int, int>
, так как это разные типы.
Но обратите внимание, что хотя они разные типы, они ведут себя одинаково, так как ключ на карте - это const
в любом случае...
Итак, в заключение. Единственное различие состоит в том, что они два разных типа, вам не следует заботиться ни о чем другом.
Разница в том, что второй вариант установит тип ключа для карты как const int
. С точки зрения "изменчивости" это избыточно, так как карта уже сохраняет свои ключи как объекты const
.
Однако это также может привести к неожиданным и неочевидным различиям в поведении этих двух карт. В С++ специализация шаблона, написанная для типа T
, отличается от специализации, написанной для типа const T
. Это означает, что вышеупомянутые две версии карты могут заканчиваться использованием различных специализаций различных "спутниковых" шаблонов, которые зависят от типа ключа. Одним из примеров является предикат ключевого компаратора. Первый использует std::less<int>
, а второй будет использовать std::less<const int>
. Используя эту разницу, вы можете легко сделать эти карты для сортировки своих элементов в другом порядке.
Такие проблемы более очевидны в новых контейнерах С++ 11, таких как std::unordered_map
. std::unordered_map<const int, int>
даже не будет компилироваться, так как он попытается использовать специализацию std::hash<const int>
для хэширования ключей. Такая специализация не существует в стандартной библиотеке.
const
не может быть изменен после установки. И да в соответствии с документами и другим ответом вы должны помнить, что key
уже const
.
Ссылка: http://www.cplusplus.com/reference/map/map/ Ссылка: http://en.cppreference.com/w/cpp/container/map
В то время как поведение вашего приложения будет, как правило, одинаковым, оно имеет значение для некоторых компиляторов, которые вы можете использовать. Более конкретный пример того, что привело меня на эту страницу, в первую очередь:
Явное указание карты как map<const key, value>
успешно завершается с помощью инструментария gnu;
Однако это приводит к сбою сборки Studio12 Solaris x86.
map<key, value>
успешно работает на обоих. Поведение приложения не изменилось.
Ключи Const могут быть полезны, если клавиши являются указателями. Использование ключей const не позволит вам изменять заостренный объект при доступе к ключам, рассмотрите это:
#include <map>
#include <string>
int glob = 10;
int main() {
std::map<const int*, std::string> constKeyMap { { &glob, "foo"} };
std::map<int*, std::string> keyMap { { &glob, "bar" } };
for(const auto& kv : keyMap) { *(kv.first) = 20; }; // glob = 20
for(const auto& kv : constKeyMap) { *(kv.first) = 20; }; // COMPILE ERROR
return 0;
}
Как указано гонорами Lightness на орбите, стандарт официально требует, чтобы ваш тип ключа можно было копировать и перемещать. Теперь это обеспечивается RTM для Visual Studio 2015.
На этой платформе: std::map<const Key,Value>
не будет компилироваться.
const ссылается на константу, которая после того, как она определена, не может быть изменена, тогда... non const ключ подвергается изменению... или даже не может измениться, просто "без изменений" гарантируется в const ( после определения), а "изменение" может иметь место или не иметь место в неконтактных файлах.