Everyone encounters this issue at some point:
for(const auto& item : items) {
cout << item << separator;
}
... and you get an extra separator you don't want at the end. Sometime it's not printing, but, say, performing some other action, but such that consecutive actions of the same type require some separator action - but the last doesn't.
Now, if you work with old-school for loops and an array, you would do
for(int i = 0; i < num_items; i++)
cout << items[i];
if (i < num_items - 1) { cout << separator; }
}
(or you could special-case the last item out of the loop.) If you have anything that admits non-destructive iterators, even if you don't know its size, you can do:
for(auto it = items.cbegin(); it != items.cend(); it++) {
cout << *it;
if (std::next(it) != items.cend()) { cout << separator; }
}
I dislike the aesthetics of the last two, and like ranged for loops. Can I obtain the same effect as with the last two but using more spiffy C++11ish constructs?
for(const auto& item : items) {
cout << item;
} and_between {
cout << separator;
}
My way (without additional branch) is:
const auto separator = "WhatYouWantHere";
const auto* sep = "";
for(const auto& item : items) {
std::cout << sep << item;
sep = separator;
}