c++stliteratorcontainersiterator-traits

How can I get the total number of elements between two iterators?


I had written a function to test that all the elements in a container were unique.

template<class InputIt>
bool all_elements_unique(InputIt first, InputIt last){
  std::set<typename std::iterator_traits<InputIt>::value_type> s(first,last);
  return s.size() == std::distance(first,last);
}

It works. However, the size_t returned from size() and the difference_type returned from distance(), are not of the same sign.

 warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

std::distance may return negative numbers based on the direction of the iterators.

If that's the case, how could I reliably get the total number of elements between two iterators, when the amount of elements exceeds the signed maximum? I was looking for something like std::size, but it takes an entire container.


Solution

  • If that's the case, how could I reliably get the total number of elements between two iterators, when the amount of elements exceeds the signed maximum?

    If you're dealing with that many elements, do you really want to be copying it into a set everytime you call the function?

    I would either pass your container as a reference and either substitute in for your original method:

    template<class Container>
    bool all_elements_unique(Container& c) {
      std::set<typename Container::value_type> s(std::begin(c), std::end(c));
      return s.size() == c.size();
    }
    

    Or do a sort and adjacent_find:

    template<class Container>
    bool all_elements_unique(Container& c) {
      std::sort(c.begin(), c.end());
      return std::adjacent_find(c.begin(), c.end()) == c.end();
    }