2

私は持っている:

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

そしてstd::vector<MyStruct*>、要素を(を使用してstd::find_if)見つける必要がnameあり"XYZ"ます...しかし... (正しく理解できた場合)の要素は単純な関数であり、ポインターを受け取りますが、わかりPredicateませんここで、比較に使用する追加の値を指定できます。std::find_ifMyStruct"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 とラムダを使用する場合:

 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

ファンクターまたはラムダを使用する 2 つのオプションがあります。

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

ラムダを使用する 2 番目はコードが少なくなりますが、C++11 ラムダを処理できる最新バージョンのコンパイラが必要です。

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

このようにして、ラムダを再利用できます。

于 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 をサポートしている場合は、ラムダを使用して述語ファンクターを取り除くことができます。

auto it = std::find_if(vec.begin(), vec.end(), [](MyStruct* p) { return strcmp(p->name, "XYZ") == 0;});
于 2013-02-11T10:40:15.407 に答える