Nul*_*teя 70 c++ key stdmap key-value language-lawyer
以下两行有什么区别?
map<int, float> map_data;
map<const int, float> map_data;
Run Code Online (Sandbox Code Playgroud)
Lig*_*ica 62
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>; 你会得到一个新的地图类型.
在非const情况下,内部密钥类型是静止非const int:
std::map<const int, float>::key_type => const int
std::map<int, float>::key_type => int
Run Code Online (Sandbox Code Playgroud)
然而,地图键语义不变,并允许键直接访问(例如,提领迭代器,这将产生所有地图操作value_type)不constIFY的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>
Run Code Online (Sandbox Code Playgroud)
因此,如果您的实施允许,那么差异可能在很大程度上对您无关紧要.
但情况并非总是如此:标准官方要求您的密钥类型可以复制和移动,而某些实现可以重用地图节点 ; 在这些实现下,尝试使用const密钥根本不起作用.
Mar*_*oun 36
在关键的是已经const,所以它是多余的写const在这种情况下.输入元素后,key无法更改.
正如在评论中提到的,是两条线之间的区别.例如,如果您编写一个接受的函数,map<const int, int>则无法传递给它,map<int, int>因为它们是不同的类型.
但请注意,虽然它们是不同的类型,但它们的行为相同,因为地图中的键const无论如何......
总而言之.唯一的区别是它们是两种不同的类型,你不应该关心其他任何事情.
不同之处在于第二个变体将地图的键类型设置为const int.从"可修改性"的角度来看,这是多余的,因为地图已经将其键存储为const对象.
然而,这也可能导致这两个地图的行为出现意外和非明显的差异.在C++中,为类型编写的模板特化与为类型编写的特化T不同const T.这意味着地图的上述两个版本可能最终使用依赖于密钥类型的各种"卫星"模板的不同特化.一个例子是关键比较器谓词.第一个将使用,std::less<int>而第二个将使用std::less<const int>.通过利用这种差异,您可以轻松地使这些映射按不同顺序对其元素进行排序.
像新的C++ 11容器这样的问题更为明显std::unordered_map.std::unordered_map<const int, int>甚至不会编译,因为它会尝试使用std::hash<const int>专门化来散列键.标准库中不存在这种专门化.