Boost Pointer Container ライブラリをいじり、チュートリアルの例を利用してライブラリの感触をつかもうとしています。何かが足りないのかもしれませんが、ptr_map のキーとして定義した単純なクラスを保存できないようです。ただし、同じキーが ptr_set に対して機能します。
<!-- 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;
}
これにより、次の正しい出力が生成されます。
Mammal Name: anna Age: 441
Mammal Name: bobo Age: 21
Mammal Name: bobo Age: 31
Mammal Name: zublu Age: 14
ただし、MammalsContainer を ptr_map に切り替えると、コンパイルすら行われません。
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]
Pointer Container boost ページのすべてのドキュメント/例と、ptr_map に関連する多くの StackOverflow の問題を読みました。std::string や int のような単純なプリミティブ キーを使用することが、すべてのユース ケースに含まれているようです。上記の例で string/int キーがあり、Mammal クラスを値として格納すると機能します。
私が本当に構築したいのは、Key オブジェクト階層であり、特殊な operator< を提供して、並べ替えが機能するようにすることです。私の最終的なユースケースは、キーがさまざまなプロパティで構成できることです。つまり、Key1 には name 属性のみが含まれます。Key2 には、名前と場所が含まれています。さらに、マップの値もオブジェクト階層によって表されます。私は最初に
std::map<boost::shared_ptr<KeyObj>, ValueObj>
しかし、連想コンテナのポリモーフィズムを処理するより効率的なソリューションとして、ptr_container ライブラリに導かれました。あるいは、私はその結論に飛びついたのかもしれません。