2013-08-20 2 views
0

OK, 이상한 문제입니다. 해결책이 있는지 확신 할 수 없습니다.두 개의 서로 다른 std :: lists를 서로 묶는 것

두 개의 목록, 예를 들어 클라이언트 목록과 각 클라이언트 당 일부 데이터 목록이 있습니다. 클라이언트 목록을 제공하기위한 API가 있기 때문에 두 개의 목록을 두 개의 별도로 유지하는 데 관심이 있습니다.하지만 나머지 데이터는 제공하지 않으려합니다.

그러나 두 목록이 서로에 대해 정렬되어야합니다. 즉, 각 목록의 요소 n은 동일한 클라이언트를 참조해야합니다. 한 목록의 요소가 하나의 요소가 아닌 다른 요소를 연결하는 방법을 찾고 있습니다. 다른 목록의 해당 요소를 추가/제거하지 않고도 추가/제거 할 수 있지만 앞서 언급 한 API 목적을 위해 두 개의 개별 목록에 보관해야합니다.

아이디어가 있으십니까?

+0

API가'const std :: list &'를 반환해야합니까? 아니면'begin()'과'end()'이터레이터가있는 다른 것을 반환 할 수 있습니까? – aschepler

+0

[Boost.MultiIndex] (http://www.boost.org/doc/libs/1_54_0/libs/multi_index/doc/index.html) 여기로가는 방법 – TemplateRex

+0

@aschepler,'begin() '와'end()'iterators는 괜찮지 만, 요청할 때 복사 나 다른 액션을 필요로하지 않는다. – Subway

답변

0

당신이, 내가 가서 하나의 컨테이너에 넣어,하지만 단지에 액세스 할 수 있도록 사용자 정의 반복자를 사용자에게 제공 할 인터페이스를 디자인 할 수 있다면 당신은 정말 간단 캡슐화

class TwoLists{ 
    ... 
    void addNode(clientstuff a, datastuff b); 
    void removeNode(int index); 
    const std::list<clientstuff>& GetClientList(); 
private: 
    std::list<clientstuff> clientList; 
    std::list<datastuff> datalist; 
} 

void TwoLists::addNode(clientstuff a, datastuff b); 
{ 
    //add a to clientList, and add b to dataList 
} 

void TwoLists::removeNode(int n) 
{ 
    //remove node n from both lists 
} 

const std::list<clientstuff>& TwoLists::GetClientList() 
{ 
    return clientList; 
} 
+0

'GetClientList'가'const std :: list &'를 반환하면 훨씬 더 좋을 것입니다. 복사가없고 클라이언트 코드는 오래된 복사본이 아닌 '라이브'목록을 모니터링합니다. –

+0

감사합니다. –

0

을 수행 할 수 있습니다 공개 클라이언트 부분. boost::iterator_adaptor은 이런 종류의 반복자를 쉽게 작성합니다.

#include "Client.hpp" 
#include <list> 
#include <boost/iterator_adaptor.hpp> 

class ClientList { 
public: 
    class iterator; 
    class const_iterator; 
    iterator begin(); 
    const_iterator begin() const; 
    iterator end(); 
    const_iterator end() const; 

private: 
    struct InternalData { 
     //... 
    }; 
    struct ClientAndData { 
     Client client; 
     InternalData data; 
    }; 
    typedef std::list<ClientAndData> internal_list_type; 
    internal_list_type m_clients; 
    friend class iterator; 
    friend class const_iterator; 
}; 

class ClientList::iterator 
    : public boost::iterator_adaptor< 
     ClientList::iterator,      // Derived type for CRTP 
     ClientList::internal_list_type::iterator // Iter type to encapsulate 
     Client >         // Data type to expose 
{ 
private: 
    explicit iterator(const base_type& base_iter) 
     : iterator_adaptor(base_iter) {} 
    Client& dereference() const { return base()->client; } 
    friend class ClientList; 
    // Allow boost to call dereference(): 
    friend class boost::iterator_core_access; 
}; 

class ClientList::const_iterator 
    : public boost::iterator_adaptor< 
     ClientList::const_iterator, 
     ClientList::internal_list_type::const_iterator 
     const Client > 
{ 
public: 
    const_iterator(const iterator& iter) 
     : iterator_adaptor(iter.base()) {} 
private: 
    explicit const_iterator(const base_type& base_iter) 
     : iterator_adaptor(base_iter) {} 
    const Client& dereference() const { return base()->client; } 
    friend class ClientList; 
    friend class boost::iterator_core_access; 
}; 

inline ClientList::iterator ClientList::begin() 
{ return iterator(m_clients.begin()); } 

inline ClientList::const_iterator ClientList::begin() const 
{ return const_iterator(m_clients.begin()); } 

inline ClientList::iterator ClientList::end() 
{ return iterator(m_clients.end()); } 

inline ClientList::const_iterator ClientList::end() const 
{ return const_iterator(m_clients.end()); } 

또는 코드의 사용자는 const Client& 참조를 받아야하는 경우, 당신은 대부분 위의 const_iterator 클래스처럼 보일 것 하나 개 반복자 유형을 필요

.

여기에 복사되는 Client 개체는 없습니다. 사용자는 비공개 목록에있는 동일한 개체에 대한 참조를 얻습니다.

이것은 반복자 유형에 public base() 멤버 함수를 공개합니다. InternalData에서 얻으려는 누군가가 사용할 수 있습니다. 그러나 알고 있거나 알고있는 사람은 base()도 알고 있어야하거나 사용하지 않아도된다는 것을 알아야합니다. 이 문제가 걱정된다면 iterator_adaptor을 비공개로 상속 한 다음 수동으로 모든 공개 회원을 (base() 제외)으로 다시 공개 할 수 있습니다. 아니면 (아마도 더 쉬울 것입니다) InternalData의 모든 것을 비공개 또는 보호 된 다음 friend 사용할 클래스를 만듭니다.

관련 문제