我有:
std::unordered_set<ObjectRepresentation*> incompletePieces;
我想从unordered_set中获取一个对象。为此,我在循环的末尾使用了for循环和“ break”,以便循环最多运行一次。
while (incompletePieces.size()){
for (auto containedPiece : incompletePieces){ //Warning at this line that loop will run at most once
// .... doing some stuff with the contained piece
incompletePieces.erase(containedPiece);
break;
}
}
这是我想要的期望行为。问题是编译器显示警告:
循环最多运行一次(循环增量从未执行)
如何重写代码,以消除警告?是否有更好的方法从unordered_set中获取商品?
答案 0 :(得分:4)
您可以使用begin()
来获取第一个元素。
if (incompletePieces.size() > 0)
auto containedPiece = *(incompletePieces.begin());
答案 1 :(得分:2)
您提供的代码实际上确实处理了 all 个元素,并在完成时清除了它们的集合,但是这样做的方式非常简单。
有两种惯用的方法,具体取决于处理元素是否可以修改集合本身。
1)如果保证“做某事”代码不会碰到incompletePieces
(即完成一件并不会创建其他不完整的作品),那么惯用而有效的解决方案是循环遍历集合并之后清除它:
for (auto piece : incompletePieces) {
// process piece
}
incompletePieces.clear();
2)如果不是这种情况,或者您确实需要清除元素,那么惯用的解决方案仍然是基于迭代器的循环:
auto it = incompletePieces.begin();
while (it != incompletePieces.end()) {
// process *it
#if C++11
it = incompletePieces.erase(it);
#else
auto prev = it++;
incompletePieces.erase(prev);
#endif
}
答案 2 :(得分:2)
*unordered_set::begin()
将为您提供第一个元素(没有unordered_set::front()
)
我会重写:
while (incompletePieces.size()){
for (auto containedPiece : incompletePieces){
// .... doing some stuff with the contained piece
incompletePieces.erase(containedPiece);
break;
}
}
进入:
for (auto* containedPiece : incompletePieces){
// .... doing some stuff with the contained piece
}
incompletePieces.clear();
答案 3 :(得分:2)
您可以如下重写代码:
for(auto* containedPiece : incompletePieces){
//Process the set contents
}
//Clear entire set in one go
incompletePieces.clear();
如果要一次清除它,则必须使用迭代器,如下所示:
auto it = incompletePieces.begin(); //Take the pointer to first element of set
for( ; it !=incompletePieces.end() ; it++){
incompletePieces.erase(*it); //Erase one element at a time
}