const和non const key有什么区别?

以下两行有什么区别?

map<int, float> map_data; map<const int, float> map_data; 
  • intconst int是两个不同的types。

  • std::map<int, float>std::map<const int, float>类似地是不同的types。

std::map<const int, float>std::map<int, float>之间的区别在某种程度上类似于std::map<int, float>std::map<std::string, float> ; 你会得到一个新的地图types。

在非常量情况下,内部键types仍然是非const int

 std::map<const int, float>::key_type => const int std::map<int, float>::key_type => int 

但是,映射键在语义上是不可变的,所有允许直接访问键的映射操作(例如,取消引用迭代器,这会产生value_type )确实会影响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> 

因此,如果您的实施允许,差异可能在很大程度上不可见。

然而情况并非总是如此:标准正式要求您的密钥types是可复制和可移动的,并且某些实现可以重新使用映射节点 ; 在那些实现下,尝试使用const键根本无法工作。

关键是已经是const ,所以在这种情况下写const是多余的。 一旦input一个元素,其key就不能被改变。


编辑

正如评论中提到的那样,两条线是有区别的。 例如,如果您编写一个接受map<const int, int>则不能将它传递给map<int, int>因为它们是不同的types

但是请注意,虽然它们是不同的types,但它们的行为是一样的,因为映射中的键是一个const

所以最后,唯一的区别是它们是两种不同的types,你不应该在乎别的。

不同之处在于第二个变体会将映射的键types设置为const int 。 从“可修改性”的angular度来看,这是多余的,因为地图已经把它的关键字存储为const对象。

但是,这也会导致这两个地图的行为出现意想不到的和不明显的差异。 在C ++中,为typesT写的模板专门化不同于为typesconst T写的专门化。 这意味着以上两个版本的地图可能会使用不同的专门化的各种“卫星”模板,这取决于键的types。 一个例子是关键比较谓词。 第一个将使用std::less<int>而第二个将使用std::less<const int> 。 通过利用这种差异,您可以轻松地使这些地图按不同顺序排列元素。

类似std::unordered_map这样的新的C ++ 11容器,这样的问题更为明显。 std::unordered_map<const int, int>甚至不会编译,因为它会尝试使用std::hash<const int>来散列键。 标准库中不存在这样的专业化。

一旦设置, const不能被修改。 是的,根据文档和其他答案,你应该记住, keyconst已经。

链接: http : //www.cplusplus.com/reference/map/map/链接: http : //en.cppreference.com/w/cpp/container/map

虽然您的应用程序的行为通常是相同的,但它对您可能使用的某些编译器有所帮助。 什么使我到这个页面的更具体的例子:

显式指定地图为map<const key, value>用gnu工具包成功构build;

但是它会使Studio12 Solaris x86版本崩溃。


map<key, value>在两者上都成功build立。 应用程序的行为不变。

如果键是指针,则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; } 

正如轨道上的轻度赛事所述,标准正式要求您的密钥types是可复制和可移动的。 这现在由Visual Studio 2015 RTM执行。

在这个平台上:一个std::map<const Key,Value>不会被编译。

const指的是一个常量,一旦定义,就不能被改变,那么…非const键受到改变…或者甚至不能改变,只是在const(一旦定义)中保证“不变” ,而“更改”可能会或可能不会发生在非常量的东西。