Arm*_*yan 33 c++ iteration stl
我需要迭代从结尾到beginnig的向量."正确"的方式是
for(std::vector<SomeT>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit)
{
//do Something
}
Run Code Online (Sandbox Code Playgroud)
当doSomething涉及了解实际索引时,需要使用rit进行一些计算以获得它,就像 index = v.size() - 1 - (rit - v.rbegin)
如果无论如何都需要索引,那么我坚信最好使用该索引进行迭代
for(int i = v.size() - 1; i >= 0; --i)
{
//do something with v[i] and i;
}
Run Code Online (Sandbox Code Playgroud)
这会发出一个i已签名v.size()且未签名的警告.改为
for(unsigned i = v.size() - 1; i >= 0; --i) 在功能上是错误的,因为这实际上是一个无限循环 :)
什么是美学上很好的方式来做我想做的事情
我希望我不是在寻找不存在的东西:)
Rob*_*edy 56
正如您所指出的那样,条件是无条件的问题i >= 0是条件始终为真.在初始化时减去1,而不是i在每次迭代后再减1,在检查循环条件后减去1:
for (unsigned i = v.size(); i-- > 0; )
Run Code Online (Sandbox Code Playgroud)
我喜欢这种风格有几个原因:
i将UINT_MAX在循环结束时回绕,但它不依赖于该行为 - 如果类型已签名,它将工作相同.依靠无符号的环绕感觉对我来说有点像黑客.size()一次.>=.每当我在for循环中看到该运算符时,我必须重新读取它以确保没有一个一个错误.Ste*_*end 16
没有什么能阻止你的reverse_iterator循环使用索引,如多个其他答案中所述.这样,您可以根据需要在// do the work零件中使用迭代器或索引,以获得最低的额外成本.
size_t index = v.size() - 1;
for(std::vector<SomeT>::reverse_iterator rit = v.rbegin();
rit != v.rend(); ++rit, --index)
{
// do the work
}
Run Code Online (Sandbox Code Playgroud)
虽然我很想知道你需要什么索引.访问v[index]与访问相同*rit.
在美学上令人愉悦!;)
for(unsigned i = v.size() - 1; v.size() > i; --i)
Run Code Online (Sandbox Code Playgroud)
在 C++20 中可以使用范围 ( #include <ranges>)
//DATA
std::vector<int> vecOfInts = { 2,4,6,8 };
//REVERSE VECTOR
for (int i : vecOfInts | std::views::reverse)
{
std::cout << i << " ";
}
Run Code Online (Sandbox Code Playgroud)
或者如果需要保存在不同的变量中。
//SAVE IN ANOTHER VARIABLE
auto reverseVecOfInts = std::views::reverse(vecOfInts);
//ITERATION
for (int i : reverseVecOfInts)
{
std::cout << i << " ";
}
Run Code Online (Sandbox Code Playgroud)