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

C++ 在迭代过程中更改集合的最佳方法是什么?,c++,c++11,stdset,C++,C++11,Stdset,给定std::set,在时间迭代期间更改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(*i

给定std::set,在时间迭代期间更改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`
}
根据我在一些资料中读到的,这是一种不好的方式,因为:从集合中删除可能会改变集合的结构


那么,更好/最好的方法是什么

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

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

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

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

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

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

只要复印一份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::作为@Jodocus的改进移动

只需复制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);
编辑:
从@Jodocus添加std::move as improvement from@Jodocus

您必须使用函数生成的迭代器来正确更新它。但是您有可能在新项上进行迭代。开始时执行此操作有什么意义?@Jarod42现在根据您的说法可以了吗?我编辑了这个问题:空间是一个约束吗?正如你所说的,这是一个坏主意,一个新的集合将是一个简单的解决方案。@MaximeGroushkin:这取决于你必须如何使用函数中生成的迭代器来正确更新它。但是你有可能在新项上进行迭代。开始时这样做有什么意义?@Jarod42现在根据你所说的可以了吗?我编辑了这个问题:空间是一个约束吗?这是一个坏主意,就像你提到的,一个新的集合将是一个简单的解决方案。@MaximeGroushkin:这取决于操作符s=std::movemodified\s;将更接近原意而不是清晰。s=std::movemodified\u s;会更接近原意而不是清晰;足够了-@Jarod42更长,但更好吗?意图更清楚,交换是移动分配的有效实现。顺便说一句,原始数据的销毁时间也可能不同,通过交换延长到s2生存期。因为C++11,s=std::moves2;足够了-@Jarod42更长,但更好吗?意图更清楚,交换是移动分配的有效实现。顺便说一句,原始数据的销毁时间也可能与交换延长到s2寿命不同。