const和non const key有什么区别?
以下两行有什么区别?
map<int, float> map_data; map<const int, float> map_data;
-
int
和const 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
不能被修改。 是的,根据文档和其他答案,你应该记住, key
是const
已经。
链接: 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(一旦定义)中保证“不变” ,而“更改”可能会或可能不会发生在非常量的东西。