81

以下两行有什么区别?

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

7 回答 7

69
  • 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密钥根本行不通。

于 2013-07-14T13:20:57.557 回答
36

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


编辑

如评论中所述,这两行之间存在差异。例如,如果您编写一个接受的函数,map<const int, int>则不能传递给它,map<int, int>因为它们是不同的类型

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

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

于 2013-07-14T09:31:52.853 回答
9

不同之处在于第二个变体将地图的键类型设置为const int. 从“可修改性”的角度来看,这是多余的,因为映射已经将其键存储为const对象。

但是,这也可能导致这两个地图的行为出现意外和不明显的差异。在 C++ 中,为 type 编写的模板特化T不同于为 type 编写的特化const T。这意味着上述两个版本的地图最终可能会使用依赖于密钥类型的各种“卫星”模板的不同专业化。一个例子是关键比较谓词。第一个将使用std::less<int>,而第二个将使用std::less<const int>. 通过利用这种差异,您可以轻松地使这些地图以不同的顺序对它们的元素进行排序。

使用新的 C++11 容器(如std::unordered_map. std::unordered_map<const int, int>甚至不会编译,因为它会尝试使用std::hash<const int>专门的哈希键。标准库中不存在这种专业化。

于 2013-07-14T15:52:19.143 回答
3

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

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

于 2013-07-14T09:40:44.577 回答
2

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

使用 gnu 工具包显式指定地图map<const key, value>构建成功;

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


map<key, value>在两者上成功构建。应用程序的行为没有改变。

于 2013-08-15T18:18:36.177 回答
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;
}
于 2014-02-16T16:38:46.970 回答
-1

const 是指一个常数,一旦定义,就不能改变......非 const 键会发生变化......甚至不能改变,只是在 const 中保证“没有变化”(一旦定义) ,并且“更改”可能会或可能不会发生在非常量的东西中。

于 2013-07-14T15:02:34.057 回答