简体   繁体   English

在std :: vector结构中找到

[英]Finding in a std::vector of structures

I have: 我有:

struct MyStruct
{
   char* name;
   int* somethingElse;
};

And I need to find in a std::vector<MyStruct*> an element (by using std::find_if ) whose name is "XYZ" ... but ... the Predicate of std::find_if (if I have managed to understand it correctly) is a plain function, and it takes in a MyStruct pointer and I have no idea where I can specify the extra "XYZ" value to be used in the comparison. 我需要在std::vector<MyStruct*>一个元素(使用std::find_if ),其name"XYZ" ......但是...... std::find_ifPredicate (如果我有管理的话)正确理解它是一个简单的函数,它接受一个MyStruct指针,我不知道在哪里可以指定比较中使用的额外"XYZ"值。

So, how can I use std::find_if or this purpose? 那么,我怎样才能使用std::find_if或者这个目的呢? (Obviously, looking for a nice solution, not a global variable, or just walk through the list, ....) (显然,寻找一个好的解决方案,而不是一个全局变量,或者只是遍历列表,......)

Thanks, f 谢谢,f

You can use a functor for this (hope I didn't get anything wrong, as I typed it in the browser): 你可以使用一个仿函数(希望我没有弄错,因为我在浏览器中输入了它):

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);

If you use C++11 and lambda: 如果您使用C ++ 11和lambda:

 std::vector<MyStruct> mystructus;
 std::find_if(mystructus.begin(), mystructus.end(), 
             [](const MyStruct& ms){ return ms.name == std::string("XYZ"); } );

You have two options, either use functors or lamdas. 您有两种选择,使用仿函数或lamdas。

Using functors, you create a new class (or structure) whose constructor takes the string you want to search for, then it has an operator() function that is called by std::find_if : 使用仿函数,您可以创建一个新的类(或结构),其构造函数接受您要搜索的字符串,然后它有一个由std::find_if调用的operator()函数:

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"));

The second using lambdas is less code, but requires recent version of the compiler that can handle C++11 lambdas : 第二个使用lambdas的代码较少,但需要最新版本的编译器才能处理C ++ 11 lambdas

std::find_if(std::begin(...), std::end(...), [](const MyStruct* my_struct)
    { return std::string("XYZ") == my_struct->name; });

The last example can even be generalized further: 最后一个例子甚至可以进一步概括:

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"));

This way the lambda can be reused. 这样lambda可以重用。

Predicate is anything, that can have operator () applied to it (with the expected argument(s) and returns something convertible to bool). Predicate是任何东西,可以将operator ()应用于它(使用期望的参数并返回可转换为bool的东西)。 A pointer to function is such thing, but so is an object that defines operator() . 指向函数的指针就是这样,但是定义operator()的对象也是如此。

You need to provide a predicate like this: 你需要提供这样的谓词:

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;
};

Then you can std::find_if like this: 然后你可以像这样std::find_if

vector<MyStruct*>::iterator iter = std::find_if(vec.begin(), vec.end(), Comparator("XYZ"));
 if(iter != vec.end())
 {
     MyStruct* p = *iter;
 }

Or if your compiler supports C++11 you can use lambdas and get rid of the predicate functor: 或者,如果您的编译器支持C ++ 11,您可以使用lambdas并删除谓词仿函数:

auto it = std::find_if(vec.begin(), vec.end(), [](MyStruct* p) { return strcmp(p->name, "XYZ") == 0;});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM