Using auto in loops c++

让人想犯罪 __ 提交于 2019-11-28 09:36:25

A range based loop could be a cleaner solution:

for (const auto& i : a)
{

}

Here, i is a const reference to an element of container a.

Otherwise, if you need the index, or if you don't want to loop over the entire range, you can get the type with decltype(a.size()).

for (decltype(a.size()) i = 0; i < a.size(); ++i) {
}

Depending on what you want to do inside the loop and the capabilities of your compiler, range-based for loop might be a better solution.

All of your presented solutions are not bad in most situations, with minor differences Your first solution is actually worse choice and that's exactly what your compiler tells you. Second solution is better but if you want to avoid directly defining types for simplicity or some future changes, you can do the following:

auto n = a.size();
for (decltype(n) i = 0; i < n; i++) {
}

This way you bind the i and n types to always match each other.

If you used the correct literal, you'd be fine: 0U. auto sees a literal of type int, so that is the type of i. Add the U and it will see an unsigned int literal instead. Otherwise, you'd want to make use of decltype as others suggested, especially since sizeof(size_t) may be greater than sizeof(int) (it is on Windows, OS X, etc. if running in 64-bit long mode).

Trying to be const-correct whenever possible, I usually write:

const auto n(a.size());
for (auto i = decltype(n){0}; i < n; ++i)
{
}

It isn't very concise, but it's clear that you want a variable initialized to 0 of n's type (and n is const).

For discussion:

auto n = a.size();
for (auto i = n-n; i<n; ++i) {
}

Note that for types smaller than int, the substraction result widens to int (called integer promotion).

Here's a simple & cleaner solution to make it work.

for(auto i: a)
{
}

Using unsigned types would pose a problem in case of expressions like the following:

for (auto i = 0u; i < a.size() - k; ++i) ...

I propose two options instead. The first one (editors choice):

for (auto i = 0; i < static_cast<int>(a.size()); ++i) ...

and if you are fine with using a type which is bigger in size than size_t:

for (auto i = 0ll; i < a.size(); ++i) ...

Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, the operand with unsigned integer type shall be converted to the type of the operand with signed integer type. [expr.arith.conv]

for(auto n = a.size(), i = 0; i != n; ++i) {
}

...is probably the cleanest solution if you need the to access the index, as well as the actual element.

Update:

for(auto n = a.size(), i = n*0; i != n; ++i) {
}

Would be a workaround for Richard Smiths comment, although it doesn't look that clean anymore.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!