2011-12-05 15 views
8

私はクラスCMyVectorを持っています。これはCMyClassオブジェクトへのポインタのベクトルを保持しています。そして、さまざまな基準に従って要素を見つけるためのいくつかの "find"したがって、たとえば、私が持っている:述語を関数パラメータとして渡す方法

CMyClass* CMyVector::FindByX(int X); 
CMyClass* CMyVector::FindByString(const CString& str); 
CMyClass* CMyVector::FindBySomeOtherClass(CSomeOtherClass* ptr); 
// Other find functions... 

最初に、彼らはSTR、Xと一致する要素を探して、ベクトルを横断、ループとして実装され、PTRまたは任意ました。だから私はこの1つのように、述語を作成しました:

class IsSameX:public unary_function<CMyClass*, bool> 
{ 
    int num; 
public: 
    IsSameX(int n):num(n){} 
    bool operator()(CMyClass* obj) const 
    { 
     return (obj != NULL && (obj->X() == num)); 
    } 
}; 

と機能の束で終わっているすべて次のようになります。

CMyClass* CMyVector::FindByX(int x) 
{ 
    CMyVector::iterator it = find_if(vec.begin(), vec.end(), IsSameX(x)); 
    if (it != vec.end()) 
    { 
     return *it; 
    } 
    return NULL; 
} 

彼らはすべてがある述語を除いて、同じように見えます呼ばれるので、私はより多くを簡素化を考えてきましたが、この1のような機能を作成しました:

CMyClass* CMyVector::Find(ThisIsWhatIDontKnow Predicate) 
{ 
    CMyVector::iterator it = find_if(vec.begin(), vec.end(), Predicate); 
    if (it != vec.end()) 
    { 
     return *it; 
    } 
    return NULL; 
} 

そして実行します。

CMyClass* CMyVector::FindByX(int x) 
{ 
    return Find(IsSameX(x)); 
} 

など。

私の質問は:どのように私の述語を渡すことができるように私のFind関数を宣言する必要がありますか?私はいくつかの方法を試しましたが、これまでのところ運がありません。

+0

提案されているようにテンプレートの検索を別のテンプレートにラップするか、述語パラメータとして 'const std :: function&'を使うことができます。 – AJG85

答えて

10

使用テンプレートは、これまであなたがなかれも

CMyClass* CMyVector::Find(std::function<bool(const (CMYClass*)&)> Predicate) 
{ 
    CMyVector::iterator it = find_if(vec.begin(), vec.end(), Predicate); 
    if (it != vec.end()) 
    { 
     return *it; 
    } 
    return NULL; 
} 

は個人的に私はトップ1を好む(++ 11 C)のstd ::機能を使用することができます

template<typename UnaryPredicate> 
CMyClass* CMyVector::Find(UnaryPredicate Predicate) 
{ 
    CMyVector::iterator it = find_if(vec.begin(), vec.end(), Predicate); 
    if (it != vec.end()) 
    { 
     return *it; 
    } 
    return NULL; 
} 

を必要とするタイプ何に取りますインライン化が少なくて済むため、コンパイラーが最適化する方が簡単なためです。呼び出しが一意の場合は、インラインになる可能性があります。

EDIT:templatedオプションを使用するとヘッダーファイルに実装を提供する必要がありますが、これは苦痛になることがあります。一方、std ::関数はソース(.cpp)ファイル内に他のすべての実装と共に存在することができます。

+0

ありがとう、私はまだC++ 11を持っていないので、私はテンプレートの道を行く必要があります。 – MikMik

関連する問題