我有:
struct MyStruct
{
char* name;
int* somethingElse;
};
我需要找到一个std::vector<MyStruct*>
元素(使用std::find_if
)name
为"XYZ"
...但是...... {{1} } Predicate
(如果我设法正确理解它)是一个普通函数,它接收std::find_if
指针,我不知道在哪里可以指定额外的MyStruct
值用于比较。
那么,我如何使用"XYZ"
或此目的? (显然,寻找一个好的解决方案,而不是一个全局变量,或者只是遍历列表,......)
谢谢,f
答案 0 :(得分:4)
你可以使用仿函数(希望我没有弄错,因为我在浏览器中输入了它):
class finder
{
const char* name;
public:
finder(const char* _name): name(_name) {}
bool operator()(MyStruct* elem) {return strcmp(elem->name, name) == 0;}
};
finder f("sample");
std::find_if(myvector.begin(), myvector.end(), f);
答案 1 :(得分:3)
如果您使用C ++ 11和lambda:
std::vector<MyStruct> mystructus;
std::find_if(mystructus.begin(), mystructus.end(),
[](const MyStruct& ms){ return ms.name == std::string("XYZ"); } );
答案 2 :(得分:2)
您有两个选择,使用仿函数或lamdas。
使用仿函数,您可以创建一个新的类(或结构),其构造函数接受您要搜索的字符串,然后它具有由operator()
调用的std::find_if
函数:
class my_finder
{
std::string search;
public:
my_finder(const std::string& str)
: search(str)
{}
bool operator()(const MyStruct* my_struct) const
{ return search == my_struct->name; }
};
// ...
std::find_if(std::begin(...), std::end(...), my_finder("XYZ"));
第二个使用lambdas的代码较少,但需要最新版本的编译器才能处理C++11 lambdas:
std::find_if(std::begin(...), std::end(...), [](const MyStruct* my_struct)
{ return std::string("XYZ") == my_struct->name; });
最后一个例子甚至可以进一步概括:
using namespace std::placeholders; // For `_1` used below in `std::bind`
// Declare a "finder" function, to find your structure
auto finder = [](const MyStruct* my_struct, const std::string& to_find) {
return to_find == my_struct->name;
};
auto xyz = std::find_if(std::begin(...), std::end(...), std::bind(finder, _1, "XYZ"));
auto abc = std::find_if(std::begin(...), std::end(...), std::bind(finder, _1, "ABC"));
这样可以重复使用lambda。
答案 3 :(得分:1)
Predicate
是任何可以应用运算符()
的东西(带有预期的参数,并返回可转换为bool的东西)。指向函数的指针就是这样,但定义operator()
的对象也是如此。
答案 4 :(得分:0)
您需要提供这样的谓词:
struct Comparator
{
Comparator(const char* find) : m_find(find){}
bool operator()(MyStruct* p) const
{
return strcmp(p->name, m_find) == 0;
}
const char* m_find;
};
然后你可以std::find_if
这样:
vector<MyStruct*>::iterator iter = std::find_if(vec.begin(), vec.end(), Comparator("XYZ"));
if(iter != vec.end())
{
MyStruct* p = *iter;
}
或者如果您的编译器支持C ++ 11,您可以使用lambdas并删除谓词仿函数:
auto it = std::find_if(vec.begin(), vec.end(), [](MyStruct* p) { return strcmp(p->name, "XYZ") == 0;});