I have a std::vector<std::tuple<int, int>>
which shall be able to accommodate potentially very many elements.
I do not know in advance how many elements it will have. It depends on how I run my code (with what input parameters).
I want to iterate over this vector.
At the moment, I am doing:
for (long long int idx = 0; idx <= (vec.size() - 1); idx++) {
do_something(vec[idx]);
}
This produces the warning:
warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<std::tuple<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
From SO, I understand that vec.size()
returns a std::vector<std::tuple<int, int> >::size_type
, which I understand that it potentially can not be the same as size_t
: https://stackoverflow.com/a/28514377/12248220
My question is: How shall I write the for-loop to iterate through all the elements of the vector, without warnings?
For example, an int
is not enough, I am sure the vector will hold more than 65535
elements.
Also, long unsigned int
, what the compiler tells me that .size()
returns, might be not enough to hold all the elements of my vector: from https://en.cppreference.com/w/cpp/language/types, it seems that it can go up to 4,294,967,295
only.
4 294 967 295 * 8 bytes = 34.3597384 gigabytes according to google, and yes, I do have more RAM than this (I am on a HPC server with 128 GB of ram per node).
This question can be also posed for a vector of ints only, there the multiplication above will be performed as 4 294 967 295 * 4 bytes ...
Thank you!
I understand that
vec.size()
returns astd::vector<std::tuple<int, int>>::size_type
So use it:
for (decltype(vec.size()) i = 0; i < vec.size(); ++i) {
do_something(vec[i]);
}
You can also make am explicit type alias:
using IndexType = std::vector<std::tuple<int, int>>::size_type;
for (IndexType i = 0; i < vec.size(); ++i) { ... }
Or use a range-based for loop, optionally with an index on the side:
decltype(vec.size()) i = 0;
for (auto& value : vec) { // may be `auto const&` or even just `auto`
do_something(value, i);
++i;
}
Or use iterators directly:
for (auto it = vec.begin(); it != vec.end(); ++it) {
// std::distance is constant-time with std::vector iterators (basically just `it - vec.begin()`)
auto i = std::distance(vec.begin(), it);
do_something(*it, i);
}