我需要从末尾到开头迭代一个向量。 “正确”的方法是
for(std::vector<SomeT>::reverse_iterator rit = v.rbegin(); rit != v.rend(); ++rit)
{
//do Something
}
当
//do Something
涉及到知道实际索引时,则需要使用rit
进行一些计算才能获得它,如index = v.size() - 1 - (rit - v.rbegin)
如果无论如何都需要索引,那么我坚信最好使用该索引进行迭代
for(int i = v.size() - 1; i >= 0; --i)
{
//do something with v[i] and i;
}
这会发出警告,指出
i
已签名,而 v.size()
未签名。
更改为
for(unsigned i = v.size() - 1; i >= 0; --i)
只是功能上错误,因为这本质上是一个无限循环 :)
什么是一种美观的好方法来做我想做的事情
正如您所指出的,无符号时
i >= 0
条件的问题在于该条件始终为真。不要在初始化 i
时减 1,然后在每次迭代后再次减 1,而是在检查循环条件后减 1:
for (unsigned i = v.size(); i-- > 0; )
我喜欢这种风格有几个原因:
i
将在循环结束时回绕到 UINT_MAX
,但它并不依赖于该行为 - 如果类型已签名,它的工作方式是相同的。依赖未签名的环绕对我来说感觉有点像黑客。
size()
。
>=
。每当我在
for
循环中看到该运算符时,我都必须重新读取它以确保不存在差一错误。
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
}
虽然我很想知道你需要索引做什么。访问
v[index]
与访问
*rit
相同。
for(unsigned i = v.size() - 1; v.size() > i; --i)
#include <ranges>
)
//DATA
std::vector<int> vecOfInts = { 2,4,6,8 };
//REVERSE VECTOR
for (int i : vecOfInts | std::views::reverse)
{
std::cout << i << " ";
}
或者是否需要保存在不同的变量中。
//SAVE IN ANOTHER VARIABLE
auto reverseVecOfInts = std::views::reverse(vecOfInts);
//ITERATION
for (int i : reverseVecOfInts)
{
std::cout << i << " ";
}
我更喜欢反向迭代器变体,因为它仍然很容易解释并且可以避免与索引相关的错误。
有时您可以简单地使用BOOST_REVERSE_FOREACH
,这将使您的代码如下所示:
reverse_foreach (int value, vector) {
do_something_with_the_value;
}
foreach
语句,但这样它们就变得有点不明显了:
size_t i = 0;
foreach (int value, vector) {
do_something;
++i;
}
std::vector<Type> v;
// Some code
if(v.size() > 0)
{
unsigned int i = v.size() - 1;
do
{
// Your stuff
}
while(i-- > 0);
}
i != std::numeric_limits<unsigned>::max()
...或者如果您认为它很冗长,请使用
UINT_MAX
。 或另一种方式:
for(unsigned j=0, end=v.size(), i=end-1; j<end; --i, ++j)
或 for(unsigned end=v.size(), i=end-1; (end-i)<end; --i)
for (int i = int(v.size()) - 1; i >= 0; --i) {
//do something with v[i] and i;
}
for(unsigned i = v.size() - 1; i >= 0; --i)
如果你检查一下就好了
!v.empty()
早些时候。