以下两行有什么区别?
map<int, float> map_data;
map<const int, float> map_data;
以下两行有什么区别?
map<int, float> map_data;
map<const int, float> map_data;
Answers:
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
实现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
密钥根本行不通。
So the difference is largely invisible to you in every way that matters.
-除非您使用复制/移动键的stdlib(例如libc ++),在这种情况下const版本会中断。有关相关讨论,请参见lists.cs.uiuc.edu/pipermail/cfe-dev/2011-July/015926.html。
在关键的是已经const
,所以它是多余的写const
在这种情况下。输入元素后,将key
无法更改。
正如在评论中提到的,是两条线之间的区别。例如,如果编写一个接受函数,map<const int, int>
则map<int, int>
由于它们是不同的类型,因此无法传递给它。
但是请注意,尽管它们是不同的类型,但是它们的行为相同,因为映射中的键始终是const
...
因此,总而言之。唯一的区别是它们是两种不同的类型,您无需关心其他任何事情。
std::map
将键类型公开为const
,但这并不意味着这两个模板实例与该答案可能暗示的相同。std::map<const int, float>
和std::map<int, float>
是不同的类型。
key_type
是实际上还是int
在前者的情况下。
不同之处在于第二个变体会将地图的键类型设置为const int
。从“可修改性”的角度来看,这是多余的,因为地图已经将其键存储为const
对象。
但是,这也会导致这两个地图的行为出现意料之外的差异。在C ++中,为type编写的模板专业化与为typeT
编写的专业化不同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>
两者都成功构建。应用程序的行为不变。
std::map::insert
有多个声明。
如果键是指针,则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;
}
key_type
isconst int*
为时,指针本身不是const,但指向的int
是const。