19

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 to C++. How can i return an iterator of vector from this method?

5
  • 6
    Java and C++ understand fundamentally different things by the term “iterator” so your question makes no sense (or rather, the answer isn’t what you’d expect). Commented Jan 11, 2012 at 16:12
  • 1
    That isn't really meaningful - what is your actual problem? Are you wrapping a container and want to return iterators to specific elements or ranges? Commented Jan 11, 2012 at 16:14
  • @KonradRudolph, how they are implemented is quite different, but most uses are quite similar. Commented Jan 11, 2012 at 16:14
  • 3
    @edA-qamort-ora-y No. An iterator in Java knows its container so it more closely corresponds to a range (or pair) of iterators in C++, while a C++ iterator corresponds to the iterator’s current value in Java. Commented Jan 11, 2012 at 16:15
  • Thanks for your reply. I got my answer Commented Jan 11, 2012 at 16:21

6 Answers 6

18

This will return an iterator to the beginning of types:

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

However, the caller needs to know the end() of vector types as well. Java's Iterator has a method hasNext(): this does not exist in C++.

You could 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++)
{
}
Sign up to request clarification or add additional context in comments.

2 Comments

Indeed, so you should return a pair of (begin,end) or don't bother at all.
@LightnessRacesinOrbit, was editing to illustrate what you commented.
11

You'll want to have a 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 might also want to 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();
}

Comments

4

Assuming that types is an attribute of the class Union, a nice, STL compliant, 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 Comment

Your code is wrong: Either "iterator" is a "vector of string", or "iterator" is an "iterator of a vector of string". Not both.
3

An union is a container of its members. I would use begin and end to give back iterators to the first and after-the-last members, respectively.

The list of types is not IMO the primary iterable property of an union. So I would myself use the following, and reserve the plain begin and end for the member 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();
}

Comments

3

Returning an iterator is easy. For example, you can return the first iterator in the 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 have more like an enumerator, that is, you use the method "next" to iterate from one item to the next. Thus, returning the Java iterator is enough to iterate from the begining to the end.

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

Let's iterate!

Usually, you want to iterate from the beginning to the end.

This, you need to return either the whole collection (as "const", if you want it to be readonly), and let the user iterate the way he/she wants.

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

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

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

And the, you can iterate from the beginning to the end, 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++11 version

If you provide the full container instead of only its iterators, in C++11, it becomes easier, as you can use the range-for loop (as the 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" ;
   }
}

P.S.: Johannes Schaub - litb is right in using the "const" qualifier whenever possible. I did not because I wanted to avoid to dilute the code, but in the end, "const" is your friend.

Comments

0

You can do it as below

std::vector<std::string> types

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.