【问题标题】:compare 2 iterators by address按地址比较 2 个迭代器
【发布时间】:2017-09-11 15:59:40
【问题描述】:

我定义了向量:

std::vector<int> Numbers;

另外,我定义了一个迭代器,并将其初始化到向量的开头:

std::vector<int>::iterator numIt=Numbers.begin();

我使用该迭代器通过 for 循环传递向量:

for(; numIt!=Numbers.end(); ++numIt) {
    if(func(Numbers,numIt)==true){
       return SUCCESS;
    }
}

...func 是以下函数:

bool func(std::vector<int> Numbers.end, std::vector<int>::iterator curElement){
  std::vector<int>::iterator nextElement=curElement;
  ++nextElement;
  if(nextElement== Numbers.end()){
    return false;
  }
  int ICurElement=*curElement;
  int InextElement=*nextElement;
  return ICurElement>InextElement ? true : false;
}

为什么我在func 中从来没有进入过if

完整代码

bool CurGreaterNext(std::vector<int>& set,std::vector<int>::iterator& curElement ,int size){
std::vector<int>::iterator nextElement=curElement;
  if(size == 1){
    return false;
  }
  ++nextElement;
  if(nextElement==set.end()){
    std::cout<< " im hereee "<<std::endl;
  }

  int ICurElement=*curElement;
  int InextElement=*nextElement;
  return ICurElement>InextElement ? true : false;
}

template<class TheSet , class Predicate >
void funkiFun(TheSet set , Predicate func){
  typename TheSet::iterator end=set.end();
  int count=0;
  for(typename TheSet::iterator it = set.begin(); it != end ; it++){
    if(func(set,it,set.size()-count)==true){
      std::cout << "Wo-Ho the number is "<< *it << std::endl;
      break;
    }
    count++;
  }
  std::cout <<  std::endl;
};

主要

 int main{
    int a1 = 1;
      int a2 = 2;
      int a3 = 3;
      int a4 = 4;
      int a5 = 5;
    std::vector<int> Numbers;
    Numbers.push_back(a1 );
      Numbers.push_back(a2 );
      Numbers.push_back(a3 );
      Numbers.push_back(a4 );
     Numbers.push_back(a5 );
    funkiFun<std::vector<int> >(numbers5,CurGreaterNext);
    }

【问题讨论】:

  • for(; numIt!=set.end();++ numIt) 在这一行中设置了什么?请发布您的完整代码
  • 因为你是通过副本传递向量,所以参数的结束迭代器永远不会匹配原始向量的迭代器(你的curElement,或nextElement)。您想通过 const-reference 传递 set,例如auto func(std::vector&lt;int&gt; const&amp; set, std::vector&lt;int&gt;::iterator curElement) { ... }).
  • 你的向量是空的,所以begin() == end()你永远不会进入循环。
  • @Holt ,我认为这是问题所在,但我在网站(cpprefrence)中读到 c++ 的迭代器指向元素,这并不意味着迭代器是一个指针?
  • @Quentin 我用向量检查了函数={1,2,3,4,5}

标签: c++ stl iterator


【解决方案1】:

我回答这个问题只是为了展示一种调试方式。我希望你学会它。

我做了一些修改,以便您的代码可以编译。我还添加了一些“std::cout”来查看发生了什么(您可以使用的最简单的调试工具)。

这是代码:

#include <iostream>
#include <vector>

bool CurGreaterNext(std::vector<int>& set,std::vector<int>::iterator& curElement ,int size){
std::vector<int>::iterator nextElement=curElement;
  std::cout <<"CurGreaterNext() with size= " <<size <<" (set.size()= " <<set.size() <<") nextElement *it= " <<*nextElement <<"\n";
  if(size == 1){
    std::cout <<"in CurGreaterNext() and size=1\n";
    return false;
  }
  ++nextElement;
  if(nextElement==set.end()){
    std::cout<< " im hereee "<<std::endl;
  }
  int ICurElement=*curElement;
  int InextElement=*nextElement;
  std::cout <<"ICurElement= " << ICurElement <<"  InextElement= " << InextElement <<"\n";
  return ICurElement>InextElement ? true : false;
};

template<class TheSet , class Predicate >
void funkiFun(TheSet set , Predicate func){
  typename TheSet::iterator end=set.end();
  int count=0;
  std::cout <<"at funkiFun\n";
  for(typename TheSet::iterator it = set.begin(); it != end ; it++){
    std::cout << "inside loop with count= " << count <<"\n";
    if(func(set,it,set.size()-count)==true){
      std::cout << "Wo-Ho the number is "<< *it << std::endl;
      break;
    }
    count++;
  }
  std::cout <<  std::endl;
}

int main(){
    int a1 = 1;
      int a2 = 2;
      int a3 = 3;
      int a4 = 4;
      int a5 = 5;
    std::vector<int> Numbers;
    Numbers.push_back(a1 );
      Numbers.push_back(a2 );
      Numbers.push_back(a3 );
      Numbers.push_back(a4 );
     Numbers.push_back(a5 );
    funkiFun<std::vector<int>>(Numbers,CurGreaterNext);
    }

这是输出:

at funkiFun
inside loop with count= 0
CurGreaterNext() with size= 5 (set.size()= 5) nextElement *it= 1
ICurElement= 1  InextElement= 2
inside loop with count= 1
CurGreaterNext() with size= 4 (set.size()= 5) nextElement *it= 2
ICurElement= 2  InextElement= 3
inside loop with count= 2
CurGreaterNext() with size= 3 (set.size()= 5) nextElement *it= 3
ICurElement= 3  InextElement= 4
inside loop with count= 3
CurGreaterNext() with size= 2 (set.size()= 5) nextElement *it= 4
ICurElement= 4  InextElement= 5
inside loop with count= 4
CurGreaterNext() with size= 1 (set.size()= 5) nextElement *it= 5
in CurGreaterNext() and size=1

如您所见,您的 if(nextElement==set.end()) 永远不会被调用,因为之前的比较 if(size == 1) 在之前返回。

【讨论】:

  • 我去掉了尺寸条件,还是不行
  • 如果我删除(或评论)if(size == 1) 块内的return false,它会打印“im hereee”。将您的代码与我的代码进行比较。
【解决方案2】:

原因是您的代码在外循环中递增计数,然后从 size() 中减去它,然后将其传递给您的函数。当您在最后一项时,大小(在您的谓词中)为 1,并且它在到达您期望到达的代码之前返回。

你为什么一开始就对大小和计数做这种奇怪的事情?

代码建议: 从谓词中删除计数、大小()和参数。 使用 auto 而不是从向量中声明迭代器 简化你的代码:

int ICurElement=*curElement;
int InextElement=*nextElement;
return ICurElement>InextElement ? true : false;

可能是:

return *curElement > *nextElement;

在您的谓词中,在测试 nextElement 是否结束后,如果是,则您不能稍后在函数中取消引用它。也许这应该是返回 false 而不是使用“大小”参数的情况,这很奇怪。

【讨论】:

  • 原因是用另一种方式解决问题,在我看到这种情况对我的示例没有帮助后,我删除了它,它仍然没有工作
【解决方案3】:
for (; numIt != set.end(); ++numIt) {
    if (func(Numbers, numIt) == true) {
        return SUCCESS;
    }
}

在 for 循环中,您将 (=) numIt 分配给 Numbers::end(),而不是比较 (==)。

【讨论】:

  • 你在说什么?您显示的代码 sn-p 中没有使用赋值运算符
  • 哦,我的错。现在看到了,感叹。对不起
猜你喜欢
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 2019-10-05
  • 1970-01-01
  • 1970-01-01
  • 2013-04-29
  • 2012-03-28
  • 2017-05-02
相关资源
最近更新 更多