在迭代过程中更改集合的最佳方法是什么?

时间:2018-07-04 09:45:37

标签: c++ c++11 stdset

给出std::set,在时间迭代期间更改集合的最佳方法是什么?
例如:

std::set<T> s;  // T is a some type (it's not important for the question).
// insertions to s
for (std::set<T>::iterator it = s.begin(); it != s.end(); it++) {
        T saveIt(*it);
        s.erase(*it);
        s.insert( saveIt + saveIt );  // operator+ that defined at `T`
}

根据我在某些资料中所读的内容,这是一种不好的方法,因为:从集合中删除可能会改变集合的结构。

那么什么是更好(最好)的方法呢?

2 个答案:

答案 0 :(得分:7)

您的循环可能会导致几乎无限循环,因为您不断在集合的后面添加较大的元素。直到T + T溢出为止。

正确的方法是创建一个新集合:

std::set<T> s; 
std::set<T> s2; 
for(auto const& elem : s)
    s2.insert(elem + elem);
s.swap(s2);

对于boost::range,它是单线的:

#include <boost/range/adaptor/transformed.hpp>
// ...
std::set<int> s;
s = boost::copy_range<std::set<int>>(s | boost::adaptors::transformed([](int x) { return x + x; }));

答案 1 :(得分:0)

只需复制一个std:set

std::set<T> s;
std::set<T> modified_s;
for (std::set<T>::iterator it = s.begin(); it != s.end(); it++) {
    modified_s.insert(*it+ *it);
}
s = std::move(modified_s);

编辑: 添加了std::move作为对@Jodocus的改进