我有一个函数,如果找到一个对象,则返回一个迭代器。
现在我遇到了问题。我如何解决通知调用此函数的对象未找到该对象的问题?
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?
}
我是否需要更改此数据结构?
提前致谢! :)
答案 0 :(得分:7)
返回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; });
答案 1 :(得分:5)
您可以将迭代器返回到结尾,即return class.vecCont.end()
以表示。
答案 2 :(得分:2)
如何返回结束迭代器?
您的代码变为: -
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
。
答案 3 :(得分:1)
如果找不到对象,则应返回class.vecCont.end()
。但@chris是对的 - 这正是std::find
的用途。
答案 4 :(得分:1)
像这样的东西
std::vector<obj>::iterator pos;
pos = find(coll.begin(),coll.end(), val);
不要忘记检查元素是否存在于容器中
if (pos != coll.end())
答案 5 :(得分:0)
永远不要在类中模拟std::algorithm
个函数。它们是免费的功能有一个原因。通常足以公开返回正确迭代器的begin
和end
成员函数(可能还有boost::iterator_range
)。如果你需要用仿函数做一个奇特的发现,也要暴露仿函数。
答案 6 :(得分: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
}
编辑:聪明的事情是为你的类编写一个比较器并使用std算法排序并为你找到它们。但是,做你想做的事。