2

我有:

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

我需要找到std::vector<MyStruct*>一个元素(通过使用std::find_if),它name"XYZ"......但是...... Predicatestd::find_if如果我设法正确理解它)是一个普通函数,它接受一个MyStruct指针,我不知道我可以在其中指定"XYZ"要在比较中使用的额外值。

那么,我该如何使用std::find_if或达到这个目的呢?(显然,寻找一个好的解决方案,而不是全局变量,或者只是遍历列表,....)

谢谢,

4

5 回答 5

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);
于 2013-02-11T10:39:46.350 回答
3

如果您使用 C++11 和 lambda:

 std::vector<MyStruct> mystructus;
 std::find_if(mystructus.begin(), mystructus.end(), 
             [](const MyStruct& ms){ return ms.name == std::string("XYZ"); } );
于 2013-02-11T10:42:41.030 回答
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 可以被重用。

于 2013-02-11T10:40:24.067 回答
1

Predicate是任何东西,可以将运算符()应用于它(使用预期的参数并返回可转换为 bool 的东西)。指向函数的指针就是这样,但定义 . 的对象也是如此operator()

于 2013-02-11T10:38:57.337 回答
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;});
于 2013-02-11T10:40:15.407 回答