簡體   English   中英

返回c ++迭代器

[英]returning c++ iterators

我有一個函數,如果找到一個對象,它返回一個迭代器。

現在我有一個問題。 我如何解決通知調用此函數的對象未找到該對象的問題?

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?

}

我需要改變我的數據結構嗎?

提前致謝! :)

返回vector::end() ,拋出異常,或返回除普通迭代器之外的其他東西

更好的是,不要實現自己的Find功能。 這就是<algorithm>庫的用途。 基於你的psudocode,你可以使用std::findstd::find_if find_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_person現在指向名為“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; });

您可以將迭代器返回到結尾,即return class.vecCont.end()以指示它。

如何返回結束迭代器?

你的代碼變成: -

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

如果找不到對象,則應返回class.vecCont.end() 但@chris是對的 - 這正是std::find的用途。

像這樣的東西

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

並且不要忘記檢查元素是否存在於容器中

if (pos != coll.end()) 

永遠不要在類中模擬std::algorithm函數。 它們是免費的功能有一個原因。 它通常足以暴露返回正確迭代器的beginend成員函數(可能還有boost::iterator_range )。 如果你需要用仿函數做一個奇特的發現,那么也要展開仿函數。

不要將迭代器返回到隱藏容器。 簡單地返回您想要的內容,即訪問對象(如果存在)的方法。 在這個例子中,我通過指針將對象存儲在容器中。 如果您的對象只是臨時存在,那么新對象將復制對象!

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
}

編輯:聰明的事情是為您的類編寫比較器並使用std算法排序並為您找到它們。 但是,做你想做的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM