繁体   English   中英

const 和非 const 键有什么区别?

[英]What is difference between const and non const key?

以下两行有什么区别?

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>之间的区别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 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>

因此,如果您的实施允许,那么在所有重要方面,您可能基本上看不到差异。

但是,情况并非总是如此:标准正式要求您的密钥类型是可复制和可移动的,并且某些实现会重用地图节点 在这些实现下,尝试使用const键根本行不通。

已经是const ,所以在这种情况下写const是多余的。 一旦输入了一个元素,它的key就不能改变。


编辑

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

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

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

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

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 键不会让您在访问键时修改指向的对象,请考虑:

#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 键会发生变化......甚至不能改变,只是在 const 中保证“没有变化”(一旦定义) ,并且“变化”可能会也可能不会发生在非 const 的东西中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM