C++ 为什么std::配对<;常数int,int>;不适用于某些STL容器?
似乎有些容器接受C++ 为什么std::配对<;常数int,int>;不适用于某些STL容器?,c++,c++11,stl,C++,C++11,Stl,似乎有些容器接受std::pair作为值类型,但有些容器不接受。问题当然出在const部分 我在谷歌上搜索了一下,发现只有std::vector需要拷贝可分配的数据。然而,std::pair与std::vector、std::set和std::list(可能还有其他容器)配合使用效果很好,但与std::map和std::priority_queue配合使用效果不好(后者真的让我讨厌) 以下编译没有问题(gcc 6.1.0) std::vector; vector.push_back(std::m
std::pair
作为值类型,但有些容器不接受。问题当然出在const
部分
我在谷歌上搜索了一下,发现只有std::vector
需要拷贝可分配的数据。然而,std::pair
与std::vector
、std::set
和std::list
(可能还有其他容器)配合使用效果很好,但与std::map
和std::priority_queue
配合使用效果不好(后者真的让我讨厌)
以下编译没有问题(gcc 6.1.0)
std::vector;
vector.push_back(std::make_pair(3,5));
std::set;
设置插入(标准::制作配对(3,5));
std::列表;
列表。推回(std::生成一对(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);
std::优先级队列pq;
产品质量推送(标准:制造(3,5)对);
地图;
map[2]=std::make_对(3,5);
错误:分配只读成员'std::pair::first'
这背后的原因是什么?如果std::map
和std::set
具有相同的底层实现,那么它们不应该具有相同的行为吗?尽管它需要移动数据,但为什么它能与std::vector一起工作?问题
让我们更深入地了解您的错误:
错误:分配只读成员“std::pair::first”
解决方案
这是没有办法的!正如您在这里看到的,有一个成员仅处于读取模式
std::priority_queue<std::pair<const int, int>> pq;
std::优先级队列pq;
在这里您可以看到const int
。嗯,const
修饰符使变量只能处于读取模式,并且不能更改!这是你的问题。如果您试图分配一个常数,那么这会导致一个错误,因为您试图在常数处于只读模式时更改该常数
工具书类
任何需要分配的任务都将中断
不需要赋值,只需要复制/移动构造vector::push_back
set::insert与之相同
列表同上::向后推
需要在现有元素周围移动以维护heap属性(通过priority\u queue::push
),这需要赋值std::push\u heap
map[2]=stuff代码>实际上是一个赋值。如果您想让它工作,请使用
或map::insert
map::emplace
const
元素。我不理解你的困惑。您正在尝试赋值,并抱怨无法赋值给常量。@S.K.:vector[0]=std::make_pair(3,5)代码>也不行。@KerrekSB我不是在抱怨,我只是想了解为什么不同的容器行为不同,以及这是否是一种预期的行为。这些容器是为非常量内容编写的,而您得到的行为大多是巧合的,这取决于库编写者在实现非常量变体时所做的事vector::push_back
实际上需要移动元素。@Slava它是重新分配时的复制/移动构造,而不是赋值。@Slava它是。我在哪里说过不需要?那么我不明白为什么std::vector
移动元素不需要赋值,而std::push_heap
则需要赋值。从向量或deque中删除元素也需要赋值。
error: assignment of read-only member ‘std::pair<const int, int>::first’
std::priority_queue<std::pair<const int, int>> pq;