以下两行有什么区别?
map<int, float> map_data;
map<const int, float> map_data;
答案 0 :(得分:59)
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
但是,映射键是语义不可变的,并且所有允许直接访问键的映射操作(例如,解除引用迭代器,产生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>
因此,如果您的实施允许, 的差异在很大程度上对您来说是不可见的。
但情况并非总是如此:标准正式要求您的密钥类型可以复制和移动,some implementations re-use map nodes;在这些实现下,尝试使用const
密钥根本不起作用。
答案 1 :(得分:37)
key已经const
,因此在这种情况下编写const
是多余的。输入元素后,无法更改其key
。
正如评论中所提到的,这两行之间存在 差异。例如,如果您编写的函数接受map<const int, int>
,则无法传递给它map<int, int>
,因为它们是不同的类型。
但请注意,虽然它们是不同的类型,但它们的行为相同,因为地图中的键无论如何都是const
......
总而言之。唯一的区别是它们是两种不同的类型,你不应该关心其他任何类型。
答案 2 :(得分:8)
不同之处在于第二个变体会将地图的键类型设置为const int
。从“可修改性”的角度来看,这是多余的,因为地图已将其密钥存储为const
个对象。
然而,这也可能导致这两个地图的行为出现意外和非明显的差异。在C ++中,为类型T
编写的模板专门化与为类型const T
编写的专门化不同。这意味着地图的上述两个版本可能最终使用依赖于密钥类型的各种“卫星”模板的不同特化。一个例子是关键比较器谓词。第一个将使用std::less<int>
,而第二个将使用std::less<const int>
。通过利用这种差异,您可以轻松地使这些地图按不同顺序对其元素进行排序。
像std::unordered_map
这样的新C ++ 11容器更加明显。 std::unordered_map<const int, int>
甚至不会编译,因为它会尝试使用std::hash<const int>
专门化来散列键。标准库中不存在这种专业化。
答案 3 :(得分:3)
const
无法更改。是的,按照文档&amp;其他答案你应该记住,key
已经是const
。
链接:http://www.cplusplus.com/reference/map/map/ 链接:http://en.cppreference.com/w/cpp/container/map
答案 4 :(得分:2)
虽然应用程序的行为通常是相同的,但它会对您可能使用的某些编译器产生影响。首先让我进入此页面的更具体的例子是:
使用gnu工具包明确指定地图为map<const key, value>
;
然而,它崩溃了Studio12 Solaris x86版本。
map<key, value>
在两者上都成功构建。应用程序的行为没有改变。
答案 5 :(得分:0)
如果键是指针,则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;
}
答案 6 :(得分:-2)
const指的是一个常量,一旦定义,就不能改变......非const键会发生变化......或者甚至无法改变,只是在const中保证“无变化”(一旦定义),“改变”可能会或可能不会发生在非常数中。