17

一致するオブジェクトのオブジェクト ポインターのベクトルを検索したい。私の問題を説明するためのサンプルコードは次のとおりです。

class A {
public:
    A(string a):_a(a) {}
    bool operator==(const A& p) {
        return p._a == _a; 
    }

private: 
    string _a;
};

vector<A*> va;

va.push_back(new A("one"));
va.push_back(new A("two"));
va.push_back(new A("three"));

find(va.begin(), va.end(), new A("two"));

ベクターにプッシュされた 2 番目のアイテムを見つけたいと思います。ただし、vector はポインター コレクションとして定義されているため、C++ はオーバーロードされた演算子を使用せず、暗黙的なポインター比較を使用します。この状況で推奨される C++ の方法は何ですか?

4

4 に答える 4

17

ファンクターでfind_ifを使用します。

template <typename T>
struct pointer_values_equal
{
    const T* to_find;

    bool operator()(const T* other) const
    {
        return *to_find == *other;
    }
};


// usage:
void test(const vector<A*>& va)
{
    A* to_find = new A("two");
    pointer_values_equal<A> eq = { to_find };
    find_if(va.begin(), va.end(), eq);
    // don't forget to delete A!
}

注:あなたのoperator == for Aはconstである必要があります。または、さらに良いことに、非メンバーのフレンド関数として記述してください。

于 2008-11-03T15:03:05.423 に答える
4

std :: find_ifを使用して、適切な述語を自分で指定します。この例については、他の回答を参照してください。

または、別の方法として、boost :: ptr_vectorを見てください。これは、実際にポインターとして格納されている要素への透過的な参照アクセスを提供します(追加のボーナスとして、メモリ管理も処理されます)

于 2008-11-03T15:05:30.583 に答える
1

代わりにfind_ifを使用してみてください。これには、適切な要素が見つかったかどうかを確認する方法を正確に決定できる述語のパラメーターがあります。

http://www.sgi.com/tech/stl/find_if.html

于 2008-11-03T14:59:43.433 に答える
1

Boost::Lambda を使用することもできます。

using namespace boost::lambda;
find_if(va.begin(), va.end(), *_1 == A("two"));

もちろん、忘れずに削除する必要がないように、shared_ptrs を使用することをお勧めします。

于 2008-11-04T12:23:25.840 に答える