【问题标题】:Boost Pointer Container - can't store class as the key for ptr_mapBoost Pointer Container - 不能将类存储为 ptr_map 的键
【发布时间】:2012-01-05 18:38:40
【问题描述】:

我一直在尝试使用 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 Key 并将 Mammal 类存储为值,它就可以工作。

我真正想要构建的是一个 Key 对象层次结构,并且能够提供专门的运算符

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

但是 ptr_container 库是一种更有效的解决方案,可以处理关联容器中的多态性。或者,也许我跳到了那个结论。

【问题讨论】:

  • 听起来您已经正确诊断了问题,并且您从使用shared_ptr 的合适解决方案开始。我无法辨别真正的问题是什么。

标签: c++ shared-ptr boost-ptr-container


【解决方案1】:

ptr_map 中,只有值 (second) 由指针存储。键仍然按值存储,并且您传递的是指针,而不是值。

【讨论】:

  • 在这种情况下,为什么 ptr_set 工作方式不同,因为它也是一个关联容器,我可以在其中存储指针?
  • @killeveritt:在集合中,对象本身就是关键。如果它不接受指针,它的目的是什么? - 使用地图,您可以将 ptr-ptr、ptr-value 和 value-ptr 组合用于键值,所有这些都需要不同的实现和不同命名的类。 Boost 显然选择了最后一个,因为这可能是最常见的用例(便宜的密钥,昂贵的价值)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多