I have some code that existed in C which contains an array of uint16_t
, which looks something like uint16_t *Fingerprints;
. To iterate through it, I can pair it together with a uint32_t ArrayLength;
value and directly access Fingerprints[i]
.
Now, I am writing more code in C and I have a std::vector<uint16_t> values
that I want to iterate through the same datatype. Is it possible to get a uint16_t *
from this and pair it with values.size()
to iterate through?
CodePudding user response:
std::vector<uint16_t>
has a .data()
member function which will give you a uint16_t*
pointer and which you could use together with .size()
in the same way you were using it in C.
However, in C we usually use iterators instead of pointers if there is no specific reason to use the latter. Iterators are a generalization of the pointer concept which also applies to other kinds of containers. This has the benefit of being agnostic to the container type. If you replaced std::vector
with std::list
you wouldn't have to change anything in your code. E.g.:
std::vector<uint16_t> values;
// or e.g. `std::list<uint16_t> values`
for(auto it = values.begin(); it != values.end(); it) {
/* You can use `it` here similar to a pointer to the current element */
/* Meaning `it` is similar to `Fingerprints i` */
}
This also has the benefit that you can't accidentally mismatch the index type. How are you making sure that uint32_t
is the correct type to use for the index? What if you are on x64 and have an array/vector so large that the size can't fit in uint32_t
. It should really usually be std::size_t
(or maybe std::ptrdiff_t
if signed is preferred) for arrays/vectors instead and for other containers it might vary further.
Furthermore there is the range-for loop syntactical sugar for this which you should prefer you if you just want a simple iteration through all of the container:
for(auto&& el : values) {
/* You can use `el` here as a reference to the current element in the iteration */
/* Meaning `el` is basically `Fingerprints[i]` */
}