Skip to content

Intermediate Gotchas

The Unique Values That Stayed Duplicated

three sevens, and unique keeps every one

int main() {
  std::vector<int> ids{7, 3, 7, 3, 7};
  const auto new_end = std::unique(ids.begin(), ids.end());

  std::cout << "kept:";
  for (auto it = ids.begin(); it != new_end; ++it) std::cout << ' ' << *it;
  std::cout << '\n';
}

How many copies of 7 remain in the logical range?

Answer
kept: 7 3 7 3 7

All three remain because no two equal values are neighbors.

Why

std::unique collapses only a run whose current value compares equal to the immediately previous kept value; it never searches arbitrarily through the range. These repeated values are separated by a different number, so new_end remains ids.end(). The loop deliberately stops at that iterator, leaving the separate erase–remove trap out of this demo. Sort first when changing the order is acceptable and one copy of each value is the goal.

The fix

std::sort(ids.begin(), ids.end());
ids.erase(std::unique(ids.begin(), ids.end()), ids.end());

Takeaway: unique removes adjacent duplicates; put equal values together first if you mean to deduplicate an unsorted sequence.

Try it: g++ -std=c++17 main.cpp -o demo && ./demo

Open in Compiler Explorer ↗ Quiz this entry