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

function returning iterator in C++

本文关键字:迭代器 C++ 返回 函数      更新时间:2023-10-16

下面是一个返回迭代器的Java方法

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

我想把这段代码翻译成C++。如何从这个方法返回向量的迭代器?

这将返回一个迭代器到types:的开头

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

然而,调用者也需要知道向量typesend()。Java的Iterator有一个方法hasNext():这在C++中不存在。

您可以更改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++)
{
}

您需要一个beginend方法:

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

为了完整起见,您可能还想要const版本的

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

假设类型是类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(); }
};

联合是其成员的容器。我将使用beginend分别向第一个和最后一个成员返回迭代器。

类型列表不是联合的主要可迭代属性。因此,我将自己使用以下内容,并为成员数据本身保留普通的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();
}

返回迭代器很容易。例如,您可以返回向量类型中的第一个迭代器:

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

Java与C++

但是C++迭代器不是Java迭代器:它们的使用方式不同。

在Java(IIRC)中,您更像是一个枚举器,也就是说,您使用方法"next"从一个项迭代到下一个项。因此,返回Java迭代器就足以从开始到结束进行迭代。

在C++中,迭代器被设计为表现得像一个超级指针。因此,它通常"指向"该值,并使用运算符++、--等(取决于迭代器的确切类型),可以将迭代器移动到"指向"容器中的下一个、上一个等值。

让我们迭代

通常,您希望从开始到结束进行迭代。

这样,您需要返回整个集合(如果您希望它是只读的,则返回为"const"),并让用户按照他/她想要的方式进行迭代。

或者,您可以返回两个迭代器,一个用于开头,一个用作结尾。所以你可以有:

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

您可以在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版本

如果在C++11中提供完整的容器而不是仅提供迭代器,则会变得更容易,因为您可以使用循环的范围(如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" ;
   }
}

附言:Johannes Schaub-litb在任何可能的情况下使用"const"限定词都是正确的。我没有这样做,因为我想避免淡化代码,但最终,"const"是你的朋友。

您可以按照以下进行操作

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