我有一个迭代的矢量.在迭代时,我可能会向向量添加新值.它看起来像:
struct Foo
{
bool condition;
};
void AppendToVec(vector<Foo>& v)
{
...
v.push_back(...);
}
vector<Foo> vec;
...
for (vector<Foo>::size_type i = 0; i < vec.size(); ++i)
{
if (vec[i].condition) AppendToVec(vec);
}
Run Code Online (Sandbox Code Playgroud)
这样工作正常,事实上优雅地处理新附加元素递归需要添加更多元素的情况,但感觉有点脆弱.如果其他人出现并调整循环,它很容易被破坏.例如:
//No longer iterates over newly appended elements
vector<Foo>::size_type size = vec.size();
for (vector<Foo>::size_type i = 0; i < size; ++i)
{
if (vec[i].condition) AppendToVec(vec);
}
Run Code Online (Sandbox Code Playgroud)
要么
//Vector resize may invalidate iterators
for (vector<Foo>::iterator i = vec.begin(); i != vec.end(); ++i)
{
if (vec->condition) AppendToVec(vec);
}
Run Code Online (Sandbox Code Playgroud)
有没有最好的做法来处理这样的案件?用循环注释"警告:迭代时这个循环是故意附加到向量.谨慎改变"最好的方法?如果能让事情变得更加强大,我也愿意切换容器.
Kri*_*son 20
我解决这个问题的方法通常是创建一个我添加任何新元素的队列,然后在迭代原始容器之后,处理队列中的元素和/或将它们附加到原始元素.
这种方法的优点是,正在发生的事情是显而易见的,并且它适用于多个线程可以将新元素排入队列的情况.
sbi*_*sbi 13
如果其他人出现并调整循环,它很容易被破坏.
然后不要使用for循环,while而是使用循环.对我来说,一个for循环总是意味着使用一个简单的计时器,迭代循环.但是,如果我遇到一个while循环,我觉得事情一定是太复杂了,无法在一个简单的for循环中表达它们.我会仔细观察,我对"优化" while循环比使用for循环要小心.
允许AppendToVec更新i是否vec已使用旧向量(i-vec.begin())中的相对位置重新分配.
void AppendToVec(vector<int> & vec, vector<int>::iterator & i)
{
const int some_num = 1;
const size_t diff = i-vec.begin();
vec.push_back(some_num);
i = vec.begin()+diff;
}
int main(int argc, char* argv[])
{
const size_t arbit_size = 10;
const size_t prior_size = 3;
vector<int> vec;
// Fill it up with something
for(size_t i = 0; i < prior_size; ++i) vec.push_back(static_cast<int>(i));
// Iterate over appended elements
vector<int>::iterator i = vec.begin();
while(i != vec.end())
{
cout<<*i<<","<<vec.size()<<endl;
if(vec.size()<arbit_size) AppendToVec(vec,i);
++i;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
0,3
1,4
2,5
1,6
1,7
1,8
1,9
1,10
1,10
1,10
Run Code Online (Sandbox Code Playgroud)
您需要随机访问该向量吗?如果不是,则 anstd::list更合适。我个人认为,在迭代向量时附加到向量并不是一个好主意。