7

如果找到对象,我有一个返回迭代器的函数。

现在我有一个问题。如何解决通知调用此函数的对象找不到对象的问题?

vector<obj>::iterator Find(int id, int test)
{
        vector<obj>::iterator it;
            aClass class;

            for(it = class.vecCont.begin(); it != class.vecCont.end(); ++it)
            {
               if(found object) //currently in psuedo code
               return it;
            }

            return ???? // <<< if not found what to insert here?

}

我是否需要更改我的数据结构?

提前致谢!:)

4

7 回答 7

7

Return vector::end(),抛出异常或返回普通迭代器以外的其他内容

更好的是,不要实现自己的Find功能。这就是<algorithm>图书馆的用途。根据您的伪代码,您可能可以使用std::findor std::find_iffind_if在平等不一定意味着operator==. 在这些情况下,您可以使用 [C++11] lambda,或者如果您无法使用 C++11,则可以使用仿函数类。

由于函子是最小的公分母,我将从以下开始:

#include <cstdlib>
#include <string>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;

class Person
{
public:
    Person(const string& name, unsigned age) : name_(name), age_(age) {};

    string name_;
    unsigned age_;
};

class match_name : public unary_function <bool, string>
{
public:
  match_name(const string& rhs) : name_(rhs) {};
  bool operator()(const Person& rhs) const
  {
    return rhs.name_ == name_;
  }
private:
    string name_;
};

#include <iostream>

int main()
{
    vector<Person> people;
    people.push_back(Person("Hellen Keller", 99));
    people.push_back(Person("John Doe", 42));

    /** C++03 **/
    vector<Person>::const_iterator found_person = std::find_if( people.begin(), people.end(), match_name("John Doe"));

    if( found_person == people.end() )
        cout << "Not FOund";
    else
        cout << found_person->name_ << " is " << found_person->age_;
}

found_personnow 指向名为“John Doe”的人,否则指向people_.end()是否找不到该人。

C++11 lambda 是一种新的语言语法,它使得声明/定义函子和使用的过程在许多情况下更加简单。它是这样完成的:

string target = "John Doe";
vector<Person>::const_iterator found_person = std::find_if(people.begin(), people.end(), [&target](const Person& test) { return it->name_ == target; });
于 2012-05-09T19:33:39.373 回答
5

您可以将迭代器返回到末尾,即return class.vecCont.end()表明这一点。

于 2012-05-09T19:33:35.040 回答
3

只返回结束迭代器怎么样?

您的代码变为:-

vector<obj>::iterator Find(int id, int test)
{
   vector<obj>::iterator it;
   aClass class;

   for(it = class.vecCont.begin(); it != class.vecCont.end(); ++it)
   {
     if(found object) //currently in psuedo code
       break;
   }

   return it;
}

或者只是使用std::find.

于 2012-05-09T19:34:43.347 回答
1

class.vecCont.end()如果找不到对象,您应该返回。但是@chris 是对的——这正是std::find它的用途。

于 2012-05-09T19:33:42.110 回答
1

像这样的东西

std::vector<obj>::iterator pos;
pos = find(coll.begin(),coll.end(), val);

并且不要忘记检查您的元素是否存在于容器中

if (pos != coll.end()) 
于 2012-05-09T19:34:50.073 回答
0

永远不要在类中模拟std::algorithm函数。它们是免费功能是有原因的。公开返回正确迭代器(可能还有 a )的成员函数begin通常就足够了。如果您需要使用仿函数进行花哨的查找,请同时公开仿函数。endboost::iterator_range

于 2012-05-09T19:39:36.967 回答
0

不要将迭代器返回到隐藏的容器。简单地返回您想要的,即访问对象(如果存在)的方法。在此示例中,我通过指针将对象存储在容器中。如果您的对象只是暂时存在,那么新建一个并将对象复制过来!

class AClass;

//...some time later
std::vector<AClass*> vecCont; //notice, store pointers in this example!

//..some time later
AClass * findAClass(int id, int test)
{
  vector<AClass*>::iterator it;

  for(it = class.vecCont.begin(); it != class.vecCont.end(); ++it)
  {
     if(found object) //currently in psuedo code
     return it;
  }

  return NULL;
}

//later still..

AClass *foundVal = findAClass(1, 0);
if(foundVal)
{
  //we found it!
}
else
{
  //we didn't find it
}

编辑:明智的做法是为您的班级编写一个比较器并使用标准算法排序并为您找到它们。然而,做你想做的事。

于 2012-05-09T19:43:42.093 回答