简体   繁体   English

函数在C ++中返回迭代器

[英]function returning iterator in C++

Following is a Java method that returns an iterator 以下是返回迭代器的Java方法

vector<string> types;

// some code here

Iterator Union::types() 
{
    return types.iterator();
}

I want to translate this code to C++. 我想将此代码翻译为C ++。 How can i return an iterator of vector from this method? 如何从此方法返回vector的迭代器?

This will return an iterator to the beginning of types : 这将返回一个迭代器到types的开头:

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

However, the caller needs to know the end() of vector types as well. 但是,调用者也需要知道向量typesend() Java's Iterator has a method hasNext() : this does not exist in C++. Java的Iterator有一个方法hasNext() :这在C ++中不存在。

You could change Union::types() to return a range: 您可以更改Union::types()以返回范围:

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++)
{
}

You'll want to have a begin and end method: 你想要一个beginend方法:

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 为了完整起见,您可能还希望拥有const版本

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

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

Assuming that types is an attribute of the class Union, a nice, STL compliant, way to handle this is: 假设类型是类Union的一个属性,一个很好的,符合STL的方法来处理这个:

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(); }

};

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. 我将使用beginend分别将迭代器返回给第一个和最后一个成员。

The list of types is not IMO the primary iterable property of an union. 类型列表不是IMO联合的主要可迭代属性。 So I would myself use the following, and reserve the plain begin and end for the member data itself. 所以我自己会使用以下内容,并为成员数据本身保留plain beginend

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

std::vector<string>::const_iterator Union::types_end() const {
  return types.end();
}

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++ Java与C ++

But C++ iterators are not Java iterators: They are not used the same way. 但是C ++迭代器不是Java迭代器:它们的使用方式不同。

In Java (IIRC), you have more like an enumerator, that is, you use the method "next" to iterate from one item to the next. 在Java(IIRC)中,您更像是一个枚举器,也就是说,您使用“next”方法从一个项目迭代到下一个项目。 Thus, returning the Java iterator is enough to iterate from the begining to the end. 因此,返回Java迭代器就足以从开始到结束迭代。

In C++, the iterator is designed to behave like a super-pointer. 在C ++中,迭代器的行为类似于超指针。 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. 这个,你需要返回整个集合(如果你想要它只是“const”),并让用户按他/她想要的方式迭代。

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: 而且,你可以在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 C ++ 11版

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#): 如果你提供完整的容器而不是它的迭代器,那么在C ++ 11中,它变得更容易,因为你可以使用range-for循环(作为Java和C#中的foreach):

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 is right in using the "const" qualifier whenever possible. PS: Johannes Schaub - litb正确使用“const”限定符。 I did not because I wanted to avoid to dilute the code, but in the end, "const" is your friend. 我没有,因为我想避免稀释代码,但最后,“const”是你的朋友。

You can do it as below 你可以这样做

std::vector<std::string> types

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM