[英]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::find
或std::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
函數。 它們是免費的功能有一個原因。 它通常足以暴露返回正確迭代器的begin
和end
成員函數(可能還有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.