为什么std :: pair <const int,=“”int =“”>不适用于某些STL容器?

时间:2016-10-12 19:43:59

标签: c++ c++11 stl

似乎某些容器接受std::pair<const int, int>作为值类型,但有些容器不接受。问题当然在const部分。

我做了一些谷歌搜索,发现只有std::vector需要可复制的数据。但是,std::pair<const int, int>可以与std::vectorstd::setstd::list(可能还有其他容器)一起使用,但不能与std::mapstd::priority_queue一起使用(后者真的很烦我)。

以下编译没有问题(gcc 6.1.0)

std::vector<std::pair<const int, int>> vector;
vector.push_back(std::make_pair(3, 5));
std::set<std::pair<const int, int>> set;
set.insert(std::make_pair(3, 5));
std::list<std::pair<const int, int>> list;
list.push_back(std::make_pair(3, 5));

但是这会导致编译错误:

std::priority_queue<std::pair<const int, int>> pq;
pq.push(std::make_pair(3, 5));
std::map<int, std::pair<const int, int>> map;
map[2] = std::make_pair(3, 5);
error: assignment of read-only member ‘std::pair<const int, int>::first’

这背后的原因是什么?不应该std::mapstd::set具有相同的行为,因为它们具有相同的底层实现吗?为什么它适用于std::vector,尽管它需要移动数据?

2 个答案:

答案 0 :(得分:8)

任何需要转让的事情都会破裂。

  • vector::push_back不需要分配,只需复制/移动构造。
  • 同上[{1}}。
  • 同上[{1}}。
  • set::insert需要移动现有元素以维护堆属性(通过list::push_back),这需要分配。
  • priority_queue::push实际上是一项任务。如果您希望它起作用,请使用std::push_heapmap[2] = stuff;

答案 1 :(得分:1)

问题

让我们更深入地看一下你的错误:

  

错误:指定只读成员'std :: pair :: first'

解决方案

没有解决方案!正如您在此处所看到的,有一个成员只处于读取模式。

 std::priority_queue<std::pair<const int, int>> pq;

您可以在此处查看const int。好吧,const修饰符使得变量只能处于读取模式而不能更改!那是你的问题。如果您尝试分配常量,那么这会导致错误,因为您尝试在 READ模式下更改常量。

参考

cpprefrence