似乎某些容器接受std::pair<const int, int>
作为值类型,但有些容器不接受。问题当然在const
部分。
我做了一些谷歌搜索,发现只有std::vector
需要可复制的数据。但是,std::pair<const int, int>
可以与std::vector
,std::set
和std::list
(可能还有其他容器)一起使用,但不能与std::map
和std::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::map
和std::set
具有相同的行为,因为它们具有相同的底层实现吗?为什么它适用于std::vector
,尽管它需要移动数据?
答案 0 :(得分:8)
任何需要转让的事情都会破裂。
vector::push_back
不需要分配,只需复制/移动构造。set::insert
需要移动现有元素以维护堆属性(通过list::push_back
),这需要分配。priority_queue::push
实际上是一项任务。如果您希望它起作用,请使用std::push_heap
或map[2] = stuff;
。答案 1 :(得分:1)
让我们更深入地看一下你的错误:
错误:指定只读成员'std :: pair :: first'
没有解决方案!正如您在此处所看到的,有一个成员只处于读取模式。
std::priority_queue<std::pair<const int, int>> pq;
您可以在此处查看const int
。好吧,const
修饰符使得变量只能处于读取模式而不能更改!那是你的问题。如果您尝试分配常量,那么这会导致错误,因为您尝试在仅 READ模式下更改常量。