常量键和非常量键有什么区别

What is difference between const and non const key?

本文关键字:常量 什么 区别 非常      更新时间:2023-10-16

以下两行有什么区别?

map<int, float> map_data;
map<const int, float> map_data;
  • 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 (constkey_type

std::map<const int, float>::value_type => std::pair<const int, float>
std::map<int, float>::value_type       => std::pair<const int, float>

因此,如果您的实现允许,那么在各个重要方面,差异可能在很大程度上对您来说是不可见的。

然而,情况并非总是如此:该标准正式要求你的密钥类型是可复制和可移动的,并且一些实现重用map节点;在这些实现下,尝试使用const键根本行不通。

密钥已经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>专用化来散列密钥。标准库中不存在这种专业化。

const一旦设置就无法更改。是的,根据文档和其他答案,您应该记住key已经const了。

链接: http://www.cplusplus.com/reference/map/map/链接: http://en.cppreference.com/w/cpp/container/map

虽然应用程序的行为通常是相同的,但它会对您可能使用的某些编译器产生影响。首先将我带到此页面的更具体示例:

显式指定映射,因为map<const key, value>使用 gnu 工具包成功构建;

但是,它使Studio12 Solaris x86版本崩溃。


map<key, value>成功地建立在两者之上。应用程序的行为保持不变。

如果 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;
}

常量是指一个常量,一旦定义,就无法更改......非常量键可能会发生变化...或者甚至不能改变,只是在 const 中保证"没有变化"(一旦定义(,而"变化"可能会也可能不会发生在非 const 的东西中。