所以我想插入双所有的元素在我的set
回set
。但很明显我需要抓住结束迭代,这样我就不会继续在迭代的新元素。 (别担心,我查了一下,set::insert
不坏迭代:http://www.cplusplus.com/reference/set/set/insert/#validity)所以给出的输入,set<int> foo = { 1, 2, 3 }
,这里就是我所做的:
for(auto it = begin(foo), finish = end(foo); it != finish; ++it) {
foo.insert(*it * 2);
}
我希望我的设置包含:
1, 2, 3, 4, 6
惊喜!它包含:
-2147483648, -1073741824, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152, 65536, 98304, 131072, 196608, 262144, 393216, 524288, 786432, 1048576, 1572864, 2097152, 3145728, 4194304, 6291456, 8388608, 12582912, 16777216, 25165824, 33554432, 50331648, 67108864, 100663296, 134217728, 201326592, 268435456, 402653184, 536870912, 805306368, 1073741824, 1610612736
显然,因为我认为它没有end(foo)
不起作用。所以...如果我要保存环大小和数量来呢?
这显然是圆形的。大小以每一步增加,使得循环永远不会到达终点。
这就像说:就拿这个列表,从第一个元素开始,并继续这样做对所有的要素,当你完成后,多了一个元素添加到同一列表。
为什么会发生这种时候结束?
编辑:
回答:“那么......如果我想保存循环大小和数量来吗?”:
int size = foo.size();
std::set<int> bar;
for(auto it = begin(foo); it != end(foo); ++it) {
bar.insert(*it * 2);
}
foo.insert(bar.begin(), bar.end());
迭代器仍然有效,但作为一个std::set
是基于节点的容器中,元素总是排序,所以使用std::less<Key>
默认
看看迭代器跳转到较低的值,使之为finish
奋斗
for( ; it != finish; ++it)
{
auto t = *it ;
std::cout << "At " << t << "\n";
foo.insert( t * 2 ) ;
std::cout << "Inserted " << t*2 << "\n";
}
At 1
Inserted 2
At 2
Inserted 4 <----+
At 3 |
Inserted 6 | <---+
At 4 // jumped back -----+ |
Inserted 8 |
At 6 // Jumped back -----------+
Inserted 12
At 8
.....
这样做的一种典型的方法是通过您的源集进行迭代,并且在每个值来执行你的函数,将所述结果分成第二组。一旦你完成迭代过程,并充分产生的第二组,工会两套在一起。
如果你真的想保存循环大小和数量这一点,你可以这样做:
set<int> foo = { 1, 2, 3 };
int setSize = foo.size();
auto it = foo.begin();
for(int i = 0; i < setSize; ++i) {
foo.insert(*it * 2);
++it;
}
copy(cbegin(foo), cend(foo), ostream_iterator<int>(cout, " "));
这会给你的输出:1 2 3 4 6
我相信,你的假设是,set
被分配到与它最初有足够的空间,连续容器的重新分配是没有必要的假设一个连续的容器;在这种情况下,假定我也希望看到你的行为。 (应该尽管这指出,即使在的情况下这是一个连续的容器,容器的容量将需要验证这种假设,以避免发生不可预料的行为。)
但是,即使在你的问题,你指出insert
不坏迭代器,这意味着容器不能是连续的。事实上set
s:
通常被实现为二叉搜索树
理解这一点你真的只是继续你的循环,直到你的迭代结束指向最后叶节点。你的编译器set
实施造成的,当你插入-2147483648
元素发生,但这是依赖实现,因此可以表现不同的另一个编译器。
你要找的是定义和编译器的独立行为。取决于你的,你可以扭转在set
迭代设定内容的知识:
for(auto it = rbegin(foo); it != rend(foo); ++it) {
foo.insert(*it * 2);
}
这仅仅是一个很好的解决方案,如果插入创建这些上迭代之后被整理元素。例如,如果foo
包含负数这是不行的。你可以通过检查评估此:if(*cbegin(foo) < 0)
在else
块,你可以做反向迭代循环上述建议,但否则你需要做The Quantum Physicist's answer描述一组临时分配。