|
|
|
|
|
by duneroadrunner
3536 days ago
|
|
Yeah, maybe I didn't think the const thing through. I guess I was thinking that the benefit of using cend() is the double-check to make sure the iterator was declared as a const_iterator (when appropriate). But using "hasNext()", just like using "end()", you would lose the double-check. Perhaps I could instead claim that "item != market.end()" redundantly specifies the vector, "market", and thus presents an unnecessary opportunity for mistakes? For example: std::vector<double> x_coords;
std::vector<double> y_coords;
...
for (auto y_iter = y_coords.begin(); y_iter != y_coords.end(); y_iter++) {
for (auto x_iter = x_coords.begin(); x_iter != y_coords.end(); x_iter++) {
...
}
}
Notice the "x_iter != y_coords.end()" bug. I assume this will usually trip an assert if it is encountered in debug mode, but not in release mode. Of course you could just as easily mix up "x_iter.hasNext()" with "y_iter.hasNext()", but the removal of redundancy means one less opportunity for a potential mistake. Right? Hmm, I guess that's really an argument for losing the iterators altogether, which I guess was kind of the point of the study.So then wrt iterator invalidation, I have a question. Consider this contrived scenario: for (auto y_iter = y_coords.begin(); y_iter != y_coords.end(); y_iter++) {
if (5 == std::distance(y_coords.begin(), y_iter)) {
y_coords.resize(3);
}
}
With conventional implementations of std::vector, the "y_coords.resize(3)" will presumably "invalidate" y_iter. And the "y_iter != y_coords.end()" will result in undefined behavior. But you could imagine "safer" implementations of vector<> that would instead throw an exception (or terminate or whatever). (Or you could actually download one of them at the link I gave.) So the question is, if this "safer" implementation supported "y_iter.hasNext()", would it be better for it to throw an exception (or whatever) in this case, or just return false? |
|
The safest option is to compile this code as Rust and have it fail to satisfy the borrow checker. And basic syntax parsing because this is C++ - but ehh, details.
Certain static analysis tools may also catch the issue. Well, if you're using real C++ iterators and not ::hasNext at least.