const和非const键有什么区别?

时间:2013-07-14 09:29:25

标签: c++

以下两行有什么区别?

map<int, float> map_data;
map<const int, float> map_data;

7 个答案:

答案 0 :(得分:59)

  • intconst 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中保证“无变化”(一旦定义),“改变”可能会或可能不会发生在非常数中。