2011-11-22 1 views
0

stl::map私はキータイプがカスタム構造体です。私は、このマップが、他のコンポーネントの値に関係なく、コンポーネントとして特定の文字列(以下「id」と表記)を持つキーをすでに持っているかどうかを知りたいです。 this答えとthis 1も、私はカスタムfunctorstl::find_ifを使用しように触発さ:C++では、キーが文字列で構成されている場合、ファンクタ付きのマップ上でfind_ifを使用する方法は?

map<myStruct, vector<size_t> > myMap; 

struct myStruct 
{ 
    string a, b, c, id; 
}; 

struct checkId : unary_function<pair<myStruct, vector<size_t> >, bool> 
{ 
private: 
    string _exp; 
public: 
    checkId (myStruct x) : _exp(x.id) {} 
    bool operator() (const pair<myStruct, vector<size_t> > & p) const 
    { 
    return p.first.id.compare(_exp) == 0; 
    } 
}; 

map<myStruct, vector<size_t> >::iterator it; 
myStruct newS; // to be initialized, but not shown here 
it_mP2P = find_if(myMap.begin(), myMap.end(), checkId(newS)); 

私はこれをコンパイルすると、gccが私を返します。

/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = myStruct]’: 
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_map.h:347: instantiated from ‘_Tp& std::map<_Key,_Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = myStruct, _Tp = std::vector<long unsigned int, std::allocator<long unsigned int> >, _Compare = std::less<myStruct>, _Alloc = std::allocator<std::pair<const myStruct, std::vector<long unsigned int, std::allocator<long unsigned int> > > >]’ 
myprogram.cpp:386: instantiated from here 
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_function.h:227: error: no match for ‘operator<’ in ‘__x < __y’ 

これは私がオーバーロードしなければならないことを意味しています"<"演算子は、自分のファンクタ "checkId"を使用したい場合、私のカスタム構造体で動作しますか?これどうやってするの?私はC++のエキスパートではありませんので、事前にコードをお読みいただきありがとうございます。

+1

キーとして体mystructを使用してマップを作成するために '演算子<'(またはカスタム述語)を必要とするように見えます。 find_ifとは関係ありません。 – UncleBens

+0

ヒント:http://codepad.org/n7yWIRnQあなたのファンクタとは関係ありません –

答えて

3

http://codepad.org/VYNqdZeF

struct myStruct 
{ 
    std::string a, b, c, id; 
    bool operator<(const myStruct& rhs) const //HERES THE MAGIC 
    {return id < rhs.id;}      //WHEEEEEEEEEEEE! 
}; 

これは、カスタム比較ファンクタを通過することなく、std::map<myStruct, stuff>作業を行う必要があります。アヒルの答えをMooing

+0

ありがとう!ちなみに、 "rhs"は何かのために立っていますか?私はそれが初めてではないからです。 – tflutre

+0

「LHS

1

checkIdとは関係ありません。

map<myStruct, vector<size_t> > myMap; 

struct myStruct 
{ 
    string a, b, c, id; 
}; 

std::mapが...(それは通常、バイナリ検索ツリーとして実装されています)マップをソート(この場合はmyStruct)キータイプであるoperator<を構築するために、単純に実装されている必要があります。以下は、同じ問題を示しています地図。

高速ルックアップが必要ない場合は、vector< pair< myStruct, vector<size_t> > >を使用することができます。高速検索が必要な場合は、myStructの一部の構造を追加する必要があります。 std::mapの場合、これは比較演算子でなければなりません。代わりにstd::unordered_mapを使用することもできます(C++ 11では、これは通常ハッシュテーブルとして実装されます)。この場合、ハッシュ関数を実装する必要があります。

詳細については、std::mapおよびstd::unordered_mapのドキュメントを参照してください。

1

これはfind_ifの使用とは関係ありません。

マップのキーとなる型は、演算子<を実装するか、マップのテンプレートパラメータとしてコンパレータを提供するかのどちらかで比較可能である必要があります。

0

は、あなたが行くと

struct myStruct 
{ 
    std::string a, b, c, id; 
    bool operator<(const myStruct& rhs) const 
    {return id < rhs.id;}      
}; 

を書くならば、キーとしてmyStructを持っているすべてのマップは、ソートする必要があります行うことが最も簡単ではなく、最も柔軟

によってid

aと比較する必要のあるマップが1つあり、もう1つがbであるとします。 operator<()myStructの中に入れれば、ユーザーとstructを強く結びつけることになります。これはプログラミングの面で優れていません。

代わりに、各マップに比較する機能を設定できます

struct myStruct 
{ 
    std::string a, b, c, id; // keep your struct unchanged, and independent of clients 
}; 

bool Compare_by_a(const myStruct &s1, const myStruct& s2) { 
    return s1.a < s2.a; 
}      

bool Compare_by_b(const myStruct &s1, const myStruct& s2) { 
    return s1.b < s2.b; 
}      

bool Compare_by_id(const myStruct &s1, const myStruct& s2) { 
    return s1.id < s2.id; 
}      

map<myStruct, vector<size_t>, Compare_by_a > map1; 
map<myStruct, vector<size_t>, Compare_by_b > map2; 
map<myStruct, vector<size_t>, Compare_by_id > map3; 
関連する問題