2012-01-05 11 views
0

私はBoost Pointer Containerライブラリを使い遊んで、そのチュートリアルの例を利用してライブラリの感触を得ようとしています。たぶん私は何かが欠けているかもしれませんが、私がptr_mapのキーとして定義した単純なクラスを格納しているようには見えません。ただし、ptr_setにも同じキーが働きます。ブーストポインタコンテナ - ptr_mapのキーとしてクラスを保存できません

<!-- language: lang-cpp --> 

#include <boost/ptr_container/ptr_map.hpp> 
#include <boost/ptr_container/ptr_set.hpp> 
class mammal 
{ 
    public: 
    mammal(string name) : _name(name) {} 
    mammal(string name, int age) : _name(name), _age(age) {} 

    int age() const 
    { 
     return _age; 
    } 

    string name() const 
    { 
     return _name; 
    } 

    void eat() { cout << "Not Hungry..." << endl; } 

    bool operator<(const mammal& l) const 
    { 
     cout << " Using Mammal Impl" << endl; 
     if (name() == l.name()) 
      return age() < l.age(); 

     return name() < l.name(); 
    } 

    private: 
    string _name; 
    int _age; 
}; 


int main() 
{ 
    std::string bobo = "bobo", 
       anna = "anna", 
       zublu = "zublu"; 

    typedef boost::ptr_set<mammal> MammalsContainer; 

    MammalsContainer mammalZoo; 

    mammal* m1 = new mammal(zublu, 14); 
    mammal* m2 = new mammal(bobo, 31); 
    mammal* m3 = new mammal(anna, 441); 
    mammal* m4 = new mammal(bobo, 21); 

    mammalZoo.insert(m1); 
    mammalZoo.insert(m2); 
    mammalZoo.insert(m3); 
    mammalZoo.insert(m4); 

    for (MammalsContainer::iterator i = mammalZoo.begin(); i != mammalZoo.end(); ++i) 
    { 
     cout << " Mammal Name: " << i->name() << " Age: " << i->age() << endl; 
    } 

    return 0; 
} 

これは、以下の、正しい出力を生成します。私はMammalsContainerはptr_mapことに切り替える場合

Mammal Name: anna Age: 441 
Mammal Name: bobo Age: 21 
Mammal Name: bobo Age: 31 
Mammal Name: zublu Age: 14 

しかし、それもコンパイルされません。

typedef boost::ptr_map<mammal, int> MammalsContainer; 

    mammalZoo.insert(m1, 1); 
    mammalZoo.insert(m2, 2); 
    mammalZoo.insert(m3, 3); 
    mammalZoo.insert(m4, 4); 

結果で次のコンパイルエラー:

ptrcontainer.cpp:125: error: no matching function for call to ‘boost::ptr_map<mammal, 
int, std::less<mammal>, boost::heap_clone_allocator, std::allocator<std::pair<const 
mammal, void*> > >::insert(mammal*&, int)’ 

/usr/local/include/boost/ptr_container/ptr_map_adapter.hpp:548: note: candidates are: 
std::pair<typename boost::ptr_container_detail::ptr_map_adapter_base<T, VoidPtrMap, 
CloneAllocator, Ordered>::iterator, bool> boost::ptr_map_adapter<T, VoidPtrMap, 
CloneAllocator, Ordered>::insert(typename 
boost::ptr_container_detail::ptr_map_adapter_base<T, VoidPtrMap, CloneAllocator, 
Ordered>::key_type&, typename boost::ptr_container_detail::ptr_map_adapter_base<T, 
VoidPtrMap, CloneAllocator, Ordered>::mapped_type) [with T = int, VoidPtrMap = 
std::map<mammal, void*, std::less<mammal>, std::allocator<std::pair<const mammal, 
void*> > >, CloneAllocator = boost::heap_clone_allocator, bool Ordered = true] 

ptr_mapに関連するStackOverflowの問題の多くに加えて、Pointer Container boostページのすべてのドキュメント/例を読んだことがあります。みんなのユースケースでは、std :: stringやintのような単純なプリミティブキーの使用が関係しているようです。上記の例で文字列/ int Keyがあり、値としてMammalクラスを格納すると動作します。

本当にビルドしたいのは、キーオブジェクト階層で、ソートが機能するように特別な演算子<を提供できることです。私の最終的なユースケースは、私のキーが異なるプロパティで構成されているということです。つまり、Key1には名前属性のみが含まれています。 Key2には名前と場所が含まれています。さらに、マップの値はオブジェクト階層によっても表されます。私は当初

std::map<boost::shared_ptr<KeyObj>, ValueObj> 

を使用して始まったが、連想コンテナ中の多型を処理し、より効率的なソリューションとしてptr_containerライブラリにリードしました。あるいは、私はその結論に飛び乗ったかもしれない。

+0

あなたは問題を正しく診断したように思えますし、あなたは 'shared_ptr'を使って適切な解決策を打ち始めました。私は本当の質問が何であるかを見分けるのが難しいです。 –

答えて

2

ptr_mapには、値(second)のみがポインタによって格納されます。キーは値によってまだ格納されており、値ではなくポインタを渡しています。

+0

その場合、ptr_setは連想コンテナであり、ポインタを格納することができるので、なぜ違いますか? – killeveritt

+1

@killeveritt:セットでは、オブジェクト自体がキーです。それがポインタを取らなかった場合、その目的は何か? - マップを使用すると、キー値のptr-ptr、ptr-valueおよびvalue-ptrの組み合わせを持つことができます。これらはすべて、異なる実装と異なる名前のクラスを必要とします。 Boostは明らかに最後のものを選択しました。おそらくこれが最も一般的なユースケース(安価なキー、高価な値)であることがわかります。 – visitor

関連する問題