Function returning an iterator in C ++

The following is a Java method that returns an iterator

vector<string> types; // some code here Iterator Union::types() { return types.iterator(); } 

I want to translate this code in C ++. How can I return a vector iterator from this method?

+7
source share
6 answers

This will return the iterator to the beginning of types :

 std::vector<string>::iterator Union::types() { return types.begin(); } 

However, the caller must know the end() of the types vector. The Java Iterator has a hasNext() method: this does not exist in C ++.

You can change Union::types() to return a range:

 std::pair<std::vector<std::string>::iterator, std::vector<std::string>::iterator> Union::types() { return std::make_pair(types.begin(), types.end()); } std::pair<std::vector<std::string>::iterator, std::vector<std::string>::iterator> p = Union::types(); for (; p.first != p.second; p.first++) { } 
+12
source

You will need the begin and end method:

 std::vector<string>::iterator Union::begin() { return types.begin(); } std::vector<string>::iterator Union::end() { return types.end(); } 

For completeness, you can also have const versions

 std::vector<string>::const_iterator Union::begin()const { return types.begin(); } std::vector<string>::const_iterator Union::end()const { return types.end(); } 
+8
source

The Union is a container of its members. I would use begin and end to return iterators to the first and last members, respectively.

The list of types is not IMO the main iterable property of the union. Therefore, I myself would use the following and reserve simple begin and end for the element data itself.

 std::vector<string>::const_iterator Union::types_begin() const { return types.begin(); } std::vector<string>::const_iterator Union::types_end() const { return types.end(); } 
+3
source

Returning an iterator is easy. For example, you can return the first iterator to vector types:

 std::vector<std::string> types; // some code here std::vector<std::string>::iterator Union::returnTheBeginIterator() { return types.begin(); } 

Java vs C ++

But C ++ iterators are not Java iterators: they are not used the same way.

In Java (IIRC) you are more like an enumerator, that is, you use the "next" method to iterate from one element to another. Thus, repeating from beginning to end is enough to return the Java iterator.

In C ++, an iterator is designed to behave like a super-pointer. Thus, it usually "points" to a value, and using the ++ operator, - etc. (Depending on the exact type of iterator), you can move the iterator to a "point" to the next, previous, etc. .. in the container.

Let iteration!

Usually you want to iterate from start to finish.

This, you need to return either the entire collection (like "const" if you want it to be read-only), and let the user iterate over the way he / she wants.

Or you can return two iterators, one for the beginning and one for the end. So you could:

 std::vector<std::string>::iterator Union::typesBegin() { return types.begin(); } std::vector<std::string>::iterator Union::typesEnd() { return types.end(); } 

And you can iterate from start to finish, in C ++ 03:

 // alias, because the full declaration is too long typedef std::vector<std::string> VecStr ; void foo(Union & p_union) { VecStr::iterator it = p_union.typesBegin() ; VecStr::iterator itEnd = p_union.typesEnd() ; for(; it != itEnd; ++it) { // here, "*it" is the current string item std::cout << "The current value is " << *it << ".\n" ; } } 

C ++ Version 11

If you provide a full container instead of your iterators, in C ++ 11, this becomes easier as you can use the range-for loop (like foreach in Java and C #):

 void foo(std::vector<std::string> & p_types) { for(std::string & item : p_types) { // here, "item " is the current string item std::cout << "The current value is " << item << ".\n" ; } } 

PS: Johannes Schaub - litb fairly uses the const qualifier whenever possible. I did not do this because I wanted to avoid code erosion, but, in the end, "const" is your friend.

+2
source

Assuming types are an attribute of the Union class, a good, STL-compatible way to handle this is:

 class Union { std::vector< std::string > types public: typedef std::vector< std::string >::iterator iterator; iterator begin() { return types.begin(); } iterator end() { return types.end(); } }; 
+1
source

You can do it as below

 std::vector<std::string> types std::vector<std::string>::iterator Union::types(){ return types.begin(); } 
0
source

All Articles