Implement Java hasNext() and next() in C++ Recently came upon this question asked in interview with major tech company.


  Implement Java's next and hasNext function in your favorite
  programming language.


Here is the solution I came up with. I am not sure whether next() is implemented correctly. Here is the iterator documentation.

#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;string&gt;

template &lt;class T&gt;
class iterator {
public:
    iterator() {}
    iterator(std::vector&lt;T&gt; vec) {
        container = vec;
    }
    bool hasNext() {
        if (curr_pos == container.size()) {
            return false;
        } else {
            if (curr_pos &lt; container.size()) {
                return true;
            }
        }
        return false;
    }
    T next(){
        if (hasNext()) {
            curr_pos += 1;
            return container.at(curr_pos-1);    
        }
    }
private:
    std::vector&lt;T&gt; container;
    int curr_pos = 0;
};

int main() {
    std::vector&lt;int&gt; int_vec {1,2,3,4};
    iterator&lt;int&gt; int_it(int_vec);
    while (int_it.hasNext()) {
        std::cout &lt;&lt; int_it.next() &lt;&lt; " ";
    }

    std::cout &lt;&lt; std::endl;

    std::vector&lt;std::string&gt; str_vec {"a", "b", "c","d"};
    iterator&lt;std::string&gt; str_it(str_vec);
    while(str_it.hasNext()) {
        std::cout &lt;&lt; str_it.next() &lt;&lt; " ";
    }
    std::cout &lt;&lt; std::endl;
    std::vector&lt;int&gt; empty_vec;
    iterator&lt;int&gt; empty_it(empty_vec);
    while(empty_it.hasNext()) {
        std::cout &lt;&lt; empty_it.next() &lt;&lt; " ";
    }
    return 0;
}


Here is the working version of the above code.
I see some things that may help you improve your code.

Make sure all control paths return

Within your implementation of next(), what happens if hasNext() is not true?  The calling function will be expecting a type T but it won't get anything.  This should be addressed.

Consider throwing an error

The Java version of next() throws a NoSuchElementException if there are no more elements.  You could reproduce this behavior by actually deleting code (which would also address the above issue):

T next(){
    return container.at(curr_pos++);    
}


This works because at throws a std::out_of_range error if there are no further items.

Think carefully about signed vs. unsigned

The curr_pos member does not have a reasonable interpretation for negative values, so it would make more sense to declare it unsigned rather than int.

Prefer modern initializers for constructors

The constructor could be written using the more modern parameter intialization style.  That version would look like this:

iterator(std::vector&lt;T&gt; vec) 
    : container{vec}, curr_pos{0} 
{}


Use const where practical

The current hasNext() routine does not (and should not) modify the underlying object, and so it should be declared const:

bool hasNext() const { /* code */ }


Simplify expressions

The hasNext() routine is overly complex.  It could instead be this single line:

bool hasNext() const {
    return curr_pos &lt; container.size();
}


Use const references where practical

The constructor could and should take a const reference to avoid a copy and to preserve flexibility.  You could also use default parameters to eliminate the no-argument constructor:

iterator(const std::vector&lt;T&gt; &amp;vec = {}) 
    : container{vec}, curr_pos{0} 
{}


Consider providing an initializer list constructor

The code has a few versions of something like this:

std::vector&lt;int&gt; int_vec {1,2,3,4};
iterator&lt;int&gt; int_it(int_vec);


It would be convenient to instead be able to write this:

iterator&lt;int&gt; int_it{1,2,3,4};


Here is a constructor that will allow that usage:

iterator(const std::initializer_list&lt;T&gt;&amp; v) 
    : container{v}, curr_pos{0} 
{}