2012-01-05 5 views
0

부스트 포인터 컨테이너 라이브러리로 놀고 자습서 예제를 활용하여 라이브러리에 대한 느낌을 얻으려고했습니다. 어쩌면 나는 뭔가를 놓치고 있지만 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; 
} 

, 올바른 출력 : 나는 ptr_map가되도록 MammalsContainer을 전환 할 경우

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 문제와 함께 포인터 컨테이너 부스트 페이지의 모든 문서/예제를 읽었습니다. 모든 사람의 유스 케이스에는 std :: string 또는 int와 같은 간단한 기본 키를 사용하는 것이 포함됩니다. 위의 예제에서 string/int Key가 있고 Mammal 클래스를 값으로 저장하면 작동합니다.

내가 정말로 만들고자하는 것은 키 객체 계층이며 정렬 작업이 가능하도록 특수 연산자 <을 제공 할 수 있어야합니다. 나의 궁극적 인 유스 케이스는 나의 키가 다른 속성들로 구성 될 수 있다는 것이다. 즉, Key1은 name 속성만을 포함한다. 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 조합을 가질 수 있습니다. 이들 모두에는 다른 구현과 다른 이름의 클래스가 필요합니다. 부스트는 아마도 가장 일반적인 유스 케이스 (저렴한 키, 값 비싼 값) 일 것임을 알면 마지막으로 선택했다. – visitor