迭代器作为C ++中的函数输入?

时间:2017-05-05 12:22:07

标签: c++ iterator

我在以下简单代码中遇到问题:

  void foo (vector<int>:: iterator it, vector<int> n)
  {
       vector<int>:: iterator it2 = it +1;
       while (it2!=n.end())
       {
           cout<<*it2<<endl;
           it2++;
       }
  }
  main()
  {
        vector<int> m{1,2,3,4};
        vector<int>:: iterator it = m.begin();
        foo (it, m);
  }

我希望在终端中有2,3和4,但我在输出中得到了一些愚蠢的结果。基本上可以使用迭代器作为函数&#39;输入?这段代码有什么问题?我怎样才能使它正确?

3 个答案:

答案 0 :(得分:7)

您将vector<int> n作为副本传递。因此,您的it2指向不同的向量(在main中创建的向量)。您的检查it2!=n.end()无效,因为it2是另一个向量的迭代器。

通过引用传递n是一种解决方案。其他将通过结束迭代器而不是向量。

将矢量作为const引用传递:

void foo (vector<int>:: iterator it, const vector<int>& n)

传递结束迭代器:

void foo (vector<int>::iterator it, vector<int>::iterator end)
{
 ...
     while ( it2 != end )
 ...
}

答案 1 :(得分:3)

你有两个问题:一个是你正在传递你的矢量参数的副本,正如Satus和yeputons已经指出的那样。

第二个问题是,如果参数为空,则foo的第一行已经是非法的。也就是说,即使是微不足道的修复

void foo (vector<int>:: iterator it, vector<int> &n)
{
   vector<int>:: iterator it2 = it +1;
如果it == n.end(),则

错误。

正确的设计是用于所有库算法的设计,并且出于同样的原因:它可以正确地表达空范围。

void foo (vector<int>::iterator begin, vector<int>::iterator end)
{
   if (begin == end) return;
   for (auto i = begin; i != end; ++i)
   {
       cout<<*i<<endl;
   }
}

你的怪异跳过第一元素设计使它有点难看,一个更好的方法是让一些实用工具帮助跳过第一个元素,然后使用copy:

template <typename Iterator>
Iterator try_advance(Iterator i, int count, Iterator end)
{
  for (; count-- > 0 && i != end; ++i)
    ;
  return i;
}


void foo (vector<int>::iterator begin, vector<int>::iterator end)
{
   // skip first element of a non-empty range
   // leave an empty range un-damaged
   begin = try_advance(begin, 1, end);
   std::copy(begin, end, std::ostream_iterator<int>(std::cout, '\n'));
}

答案 2 :(得分:0)

是的,这是可能的。但请注意,迭代器与容器绑定。

您的函数的第二个参数是从参数复制构造的,即vector<int> nvector<int> m中定义的main副本。因此,您的函数尝试将迭代器与来自不同容器的另一个迭代器(.end())进行比较。你最好传递开始/结束iteratos而不是容器。