const和非const键有什么区别?

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密钥根本不起作用.

  • `因此,在重要的方方面面,差异对您来说基本上是不可见的。` - 除非您使用复制/移动键的 stdlib(如 libc++),在这种情况下,const 版本会中断。有关相关讨论,请参阅 http://lists.cs.uiuc.edu/pipermail/cfe-dev/2011-July/015926.html。 (3认同)

Mar*_*oun 36

关键的是已经const,所以它是多余的写const在这种情况下.输入元素后,key无法更改.


编辑:

正如在评论中提到的,两条线之间的区别.例如,如果您编写一个接受的函数,map<const int, int>则无法传递给它,map<int, int>因为它们是不同的类型.

但请注意,虽然它们是不同的类型,但它们的行为相同,因为地图中的键const无论如何......

总而言之.唯一的区别是它们是两种不同的类型,你不应该关心其他任何事情.

  • 这不是(完全)正确的.`std :: map`的接口将键类型暴露为`const`,但这并不意味着两个模板实例与此答案可能意味着相同.`std :: map <const int,float>`和`std :: map <int,float>`是[不同类型](http://coliru.stacked-crooked.com/view?id=d5261dd32220b034acffc54933351fac-f674c1a6d04c632b71a62362c0ccfc51) . (18认同)
  • @ johnmac2332:这是一个快速的教训!=完美,和upvotes!=正确. (6认同)
  • 没有人是完美的,我们都会犯错误并相互学习.我们来这里学习和帮助:) (2认同)
  • @LightnessRacesinOrbit 好的,是的!我同意你的看法。顺便说一句,你发布了一个很好的答案。是的,应该花时间发布并**接受**答案。我自己大部分时间都试图从基本面进行解释并发布长篇回答(当然,延迟和投票率低的帖子)。无论如何,我祝贺 Maroun 的 10K RP。Maroun 发布了许多很好的答案,我发现他是一个有价值的贡献者。 (2认同)

AnT*_*AnT 8

不同之处在于第二个变体将地图的键类型设置为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>专门化来散列键.标准库中不存在这种专门化.