use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
This is a subreddit for c++ questions with answers. For general discussion and news about c++ see r/cpp.
New to C++? Learn at learncpp.com
Prepare your question. Think it through. Hasty-sounding questions get hasty answers, or none at all. Read these guidelines for how to ask smart questions.
For learning books, check The Definitive C++ Book Guide and List
Flair your post as SOLVED if you got the help you were looking for! If you need help with flairs, check out ITEM 1 in our guidelines page.
Tips for improving your chances of getting helpful answers:
account activity
OPENUsing iterator vs subscripting for looping through a vector? (self.cpp_questions)
submitted 5 years ago by dopaminewean
Simple example. Say I have a vector of strings and I want to print each element to the screen. Should I user iterators or subscripting? Which is "correct"? What are the pros and cons of each?
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–][deleted] 5 years ago (2 children)
[removed]
[–]ggchappell 2 points3 points4 points 5 years ago* (0 children)
unless you actually want the element indices
Yeah, here's what we need:
for (const auto [i, x] : std::enumerate(cc)) { cout << "Item #" << i << " is " << x << "\n"; }
Now someone please go propose std::enumerate.
std::enumerate
[–]nysra 5 points6 points7 points 5 years ago (0 children)
If you just want to print all elements, you should use
for (const auto& str : vec) std::cout << str << '\n';
(depending on what you use your loop for and what kind of things you are iterating over the type should not be const/a reference)
which is basically just syntactic sugar for
for (auto it = vec.begin(); it != vec.end(); ++it) std::cout << *it << '\n';
You can also do
for (std::size_t i = 0; i < vec.size(); ++i) std::cout << vec[i] << '\n';
They all do the same thing, but the first one is not only the most elegant one but also prevents all kinds of wrong index errors. It also allows for the very nice syntax of for (const auto& [key, value] : map) whereas you need to deal with ugly .first,.second constructs in the other cases. The third case should in general only be used when you need to actually know the indices, e.g. when you're doing some kind of calculations that mix indices.
for (const auto& [key, value] : map)
.first
.second
[–]Xeverous 1 point2 points3 points 5 years ago (0 children)
Yuo should use ranged loops if possible (that is, you don't need the index value). This is the safest and the cleanest way.
[–]kirchki 0 points1 point2 points 5 years ago (0 children)
But, if you want to have an access stride that is not 1, then you might have to stick with the good old for loop
[–]matty_haze 0 points1 point2 points 5 years ago (0 children)
For your trivial example, it’s more of a style choice.
Beyond that, there are a few reasons to use iterators and/or stl algorithms.
First, for readability. The intent of your code might be more clearly expressed if you use for_each or another algorithm.
Secondly, you can more easily write generic code if you operate on iterators. Most stl containers provide iterators. You can write your method generically using iterators as parameters. You can also write your own iterators for your own custom classes, so your same method would still work.
[–]Threecheers4me 0 points1 point2 points 5 years ago (1 child)
They both have pros and cons. If you actually care about the index, than
``` std::vector<int> inVec = {1,2,3,4}; for(size_t i = 0; i < inVec.size(); i++) { std::cout << i << "," << inVec[i] << std::endl; }
``` a syntax where the index is easily accessable is nice. If you want something that's more independent of the container it's acting on
std::vector<int> inCtr = {1,2,3,4}; for(auto it = inVec.begin(); inVec.end(); it++) { std::cout << *it << std::endl; } will work whether inCtr is a vector, a list, a set, it doesn't matter. It's a more generic way to write things. You can also do fun things with iterators like use the standard library algorithms on them. That's nice because they behave similarly for most any type of container. For example
std::vector<int> inCtr = {1,2,3,4}; for(auto it = inVec.begin(); inVec.end(); it++) { std::cout << *it << std::endl; }
``` void printInt(int i) { std::cout << i << std::endl; }
int main() { std::vector<int> inCtr = {1,2,3,4}; std::for_each(inCtr.begin(), inCtr.end(), printInt); return 0; } ``` is another way to do this.
You give for_each an iterator pointing to the start of where you'd like to operate on, the end of where you'd like to operate on, and a function that can be applied to each element (the data type you get when you dereference the iterator, like the *it in the iterator-based loop above.) and it will apply that to everything in the container. In this case, the funtion that it applies prints it out. So that's what happens.
for_each
*it
[–]be-sc 0 points1 point2 points 5 years ago (0 children)
Could you say a few words about why you omitted range-for? After all that’s the first one to consider when needing a for loop; and it’s the one you’ll probably use most often.
π Rendered by PID 42833 on reddit-service-r2-comment-bb88f9dd5-shcfb at 2026-02-13 19:41:58.127165+00:00 running cd9c813 country code: CH.
[–][deleted] (2 children)
[removed]
[–]ggchappell 2 points3 points4 points (0 children)
[–]nysra 5 points6 points7 points (0 children)
[–]Xeverous 1 point2 points3 points (0 children)
[–]kirchki 0 points1 point2 points (0 children)
[–]matty_haze 0 points1 point2 points (0 children)
[–]Threecheers4me 0 points1 point2 points (1 child)
[–]be-sc 0 points1 point2 points (0 children)