1

I have a foreach loop that goes though a std::set that looks like

for (auto& line : lines){
    //use line
    bool end = /* Check if line is the last element */
}

With a std::vector I could check &line == &lines.back();

Is there a way I can do something similar for a std::set?

PomfCaster
  • 812
  • 1
  • 7
  • 12

3 Answers3

2

No, because a set doesn't have a front or a back. However, you could if you used iterators:

for (auto iter = lines.begin(); iter != lines.end(); iter++)
{
    bool end = iter + 1 == set.end();
}

Alternatively, you could count how many items you've iterated through:

size_t count = 0;
for (auto& line : lines)
{
    count++;
    if (count == set.size()) // this is the last element
}
zneak
  • 134,922
  • 42
  • 253
  • 328
0

zneak has some pretty good ideas, but here's one involving iterators in the loop:

std::set<std::string> lines;
lines.insert("Hello");
lines.insert("Thar");
lines.insert("How");
lines.insert("Goes");
lines.insert("It");
for (const auto& line : lines) {
    auto it = lines.find(line);
    it++;
    std::cout << std::boolalpha << (it == lines.end()) << std::endl;
}
  • Hopefully you realize that your solution runs in logarithmic time. Logarithmic is usually pretty good, but for something so easy to do in constant time, it's slightly disappointing. – zneak Dec 06 '13 at 06:44
0

How about this way,

auto iter = lines.cend();
if (iter!=lines.cbegin())
    --iter;
for (auto &line : lines)
{
    if (*iter==line) // end of the set
    {}
}
Deidrei
  • 2,125
  • 1
  • 14
  • 14