如何获取std::set的第一个元素

16

大家好,

我在我的软件中发现了一个奇怪的错误。

在一个while循环内,我从std::set中删除元素,我想一直取第一个元素,直到容器为空:

std::set< int*> nodes;
// Fill nodes 
for (int i=0; i<10;i++)
   nodes.insert(new int);
//
while (!nodes.empty())
{
int* pivot  = (*nodes.begin());
// do some operation with pivot erasing some elements from nodes
}

我发现使用这种方式实现第一个元素可以在gcc上运行,但在MSVC上不行,当我尝试解引用(*nodes.begin())迭代器时会崩溃。

std::set的两种实现行为是否不同?

我想要一个没有实现差异的数据结构,这可能吗?

可能我必须更改数据结构才能进行此类操作。


5
“对节点进行一些操作并擦除其中的某些元素”是什么意思? - Andreas Brinck
5
这个表达式的意思是这样的:使用 *(nodes.begin()) 来进行解引用操作。 - v01d
2
请提供一个完整的测试用例,而不仅仅是这个片段。 - Oliver Charlesworth
2
@v01d,这应该没有任何影响,除非实现有问题,“.”应该比“*”具有更高的优先级。(非常糟糕的实现) - Shep
5
不,它并不会,问题几乎肯定出现在你没有发布的代码中。 - Andreas Brinck
显示剩余11条评论
2个回答

2

你的代码在VS2010中工作良好,也许你应该更新你的VCC。


-2

在这样的集合上使用迭代器是不可行的,因为从集合中删除元素会使迭代器失效。当集合的大小低于某个阈值(基于设置迭代器时的初始大小)时,它将修改堆上数据的底层存储,这将导致作为迭代器的指针指向无用的内容。

请参见迭代器有效性: http://www.cplusplus.com/reference/set/set/erase/

(*nodes.begin())可以实现你想要的功能,但你不能从正在迭代的集合中删除元素。


为什么会有没有任何评论的踩? - undefined
你不能像这样在集合上使用迭代器,因为从集合中删除一个元素会使迭代器失效...你不能在迭代过程中删除集合中的元素。- 我认为你是错的:你可以从代码片段中看到,OP在每次迭代开始时初始化迭代器,所以我不认为这是一个问题。 - undefined
这句话的意思是,它将修改堆上存储的数据,这将导致作为迭代器的指针指向无用的数据。实际上,我不太理解这个说法。如果标准容器按照你所说的做法,那将是一场灾难。在调整大小时,内部数据(即int指针的值)不应该发生变化。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接