В чем разница между const и non const key?
В чем разница между двумя строками?
map<int, float> map_data;
map<const int, float> map_data;
Ответы
Ответ 1
-
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
просто не будет работать.
Ответ 2
Клавиша уже const
, поэтому в этом случае избыточно писать const
. После ввода элемента его key
не может быть изменен.
Изменить:
Как упоминалось в комментариях, разница между между двумя строками. Например, если вы пишете функцию, которая принимает map<const int, int>
, вы не можете передать ей map<int, int>
, так как это разные типы.
Но обратите внимание, что хотя они разные типы, они ведут себя одинаково, так как ключ на карте - это const
в любом случае...
Итак, в заключение. Единственное различие состоит в том, что они два разных типа, вам не следует заботиться ни о чем другом.
Ответ 3
Разница в том, что второй вариант установит тип ключа для карты как 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>
для хэширования ключей. Такая специализация не существует в стандартной библиотеке.
Ответ 4
const
не может быть изменен после установки. И да в соответствии с документами и другим ответом вы должны помнить, что key
уже const
.
Ссылка: http://www.cplusplus.com/reference/map/map/
Ссылка: http://en.cppreference.com/w/cpp/container/map
Ответ 5
В то время как поведение вашего приложения будет, как правило, одинаковым, оно имеет значение для некоторых компиляторов, которые вы можете использовать. Более конкретный пример того, что привело меня на эту страницу, в первую очередь:
Явное указание карты как map<const key, value>
успешно завершается с помощью инструментария gnu;
Однако это приводит к сбою сборки Studio12 Solaris x86.
map<key, value>
успешно работает на обоих. Поведение приложения не изменилось.
Ответ 6
Ключи 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;
}
Ответ 7
Как указано гонорами Lightness на орбите, стандарт официально требует, чтобы ваш тип ключа можно было копировать и перемещать. Теперь это обеспечивается RTM для Visual Studio 2015.
На этой платформе: std::map<const Key,Value>
не будет компилироваться.
Ответ 8
const ссылается на константу, которая после того, как она определена, не может быть изменена, тогда... non const ключ подвергается изменению... или даже не может измениться, просто "без изменений" гарантируется в const ( после определения), а "изменение" может иметь место или не иметь место в неконтактных файлах.