VC ++ 2010
假设我有以下内容:
struct person {
char * name;
int age;
};
然后我有一个包含这些的载体:
std::vector <person> person_list;
现在,在推回其中一些元素后,如何根据其中一个属性找到一个元素?最好的情况,我希望它返回一个指向矢量元素'where name = string'
交易类型的指针。
答案 0 :(得分:2)
(请使用std::string
代替char*
,以避免泄漏或悬挂指针。)
您可以使用std::find_if
来获取该元素的迭代器:
#include <algorithm> // allow us to use std::find_if
struct NameFinder
{
std::string target;
bool operator()(const person& pers) const
{
return pers.name == target;
}
};
...
NameFinder finder;
finder.target = "whatever name you want";
std::vector<person>::iterator it =
std::find_if(person_list.begin(), person_list.end(), finder);
std::cout << "name = " << it->name << "; age = " << it->age << std::endl;
这里的NameFinder是一个函数对象,它检查一个人的名字是否与给定目标匹配。
答案 1 :(得分:1)
改善的一个建议。使用std::string
代替char*
。你必须#include <string>
。
在C ++ 11中,您可以使用lamda和std::find_if
作为:
#include <algorithm>
auto it = std::find_if(persons.begin(), persons.end(), [](const person & p)
{
return p.name = "string";
});
在C ++ 03中,您可以使用functor作为谓词:
#include <algorithm>
struct name_predicate
{
std::string name;
name_predicate(std::string const & name) : name(name) {}
bool operator()(person const & p) { return name == p.name; }
};
std::vector<person>::iterator it = std::find_if(persons.begin(),
persons.end(),
name_predicate("string"));
答案 2 :(得分:1)
stdlib使用迭代器而不是指针。在algorithm
标题中,您会找到功能模板find
和find_if
。第一个按值标识搜索元素,第二个按谓词搜索,并返回iterator
到第一个匹配。您可以将operator==
的重载添加到您的person类,并使用第一个版本或编写谓词,然后使用第二个版本。
这是一个示例谓词:
struct person_equal {
bool operator()(const person& p, const char* name) {
return strcmp(p.name, name);
}
};
请注意,它使用C函数strcmp
。您应该将std::stringS
存储在person
个对象中,而不是char*
。
现在,这个谓词有两个元素,但find_if
需要一元谓词。您需要将bind
第二个参数设置为某个固定值。在这里,我使用已弃用的bind2nd
。您应该使用boost:::bind
或C ++ TR1替换。
std::find_if(vec.begin(), vec.end(), std::bind2nd(person_equal(), "foobar"));
在C ++ 0x中,您将使用lambda:
std::find_if(v.begin(), v.end(), [](const person& p) { return strcmp(p.name, "foobar"); });
或者你可以迭代:
std::vector<person>::iterator my_find(std::vector<person>& v) {
for(std::vector<person>::iterator it = v.begin(), it != v.end(), ++it) {
if(strcmp(it->name, "foobar")) return it;
}
}