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]` */
}
