Контейнер повышения указателя - не может сохранить класс в качестве ключа для ptr_map

Я пытался поиграть с библиотекой 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, а также множество проблем Stackru, связанных с ptr_map; кажется, что каждый случай использования включает использование простого примитивного ключа, такого как std::string или int. Это работает, если у меня есть ключ string/int в приведенном выше примере, и в качестве значения сохранен класс Mammal.

То, что я действительно хочу построить, это иерархия ключевых объектов и возможность предоставить специализированный оператор<, чтобы сортировка могла работать. Мой возможный вариант использования состоит в том, что мои ключи могут состоять из разных свойств, т.е. ключ 1 содержит только атрибут имени; Key2 содержит имя и местоположение. Кроме того, значение карты также представлено иерархией объектов. Я изначально начал с использованием

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

но был приведен к библиотеке ptr_container как к более эффективному решению, которое обрабатывает полиморфизм в ассоциативных контейнерах. Или, может быть, я пришел к такому выводу.

1 ответ

Решение

В ptr_map только значение (second) хранится по указателю. Ключ по-прежнему сохраняется по значению, и вы передаете указатель, а не значение.

Другие вопросы по тегам