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

carvr3hs  于 2023-02-06  发布在  其他
关注(0)|答案(6)|浏览(171)

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

vector<string> types;

// some code here

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

我想把这段代码翻译成C++。我怎样才能从这个方法返回一个向量的迭代器呢?

uxhixvfz

uxhixvfz1#

这将返回一个迭代器到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++)
{
}
ql3eal8s

ql3eal8s2#

你需要一个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();
}
2izufjch

2izufjch3#

假设types是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(); }
};
wvmv3b1j

wvmv3b1j4#

联合体是其成员的容器,我将使用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();
}
0pizxfdo

0pizxfdo5#

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

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中,如果你提供完整的容器,而不仅仅是它的迭代器,那么这会变得更容易,因为你可以使用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" ;
   }
}

P.S.:Johannes Schaub - litb在可能的情况下使用“const”限定符是正确的。我没有这样做是因为我想避免稀释代码,但最终,“const”是你的朋友。

qoefvg9y

qoefvg9y6#

您可以按以下步骤操作

std::vector<std::string> types

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

相关问题