을 수행 할 수 있습니다 공개 클라이언트 부분. 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
사용할 클래스를 만듭니다.
API가'const std :: list &'를 반환해야합니까? 아니면'begin()'과'end()'이터레이터가있는 다른 것을 반환 할 수 있습니까? –
aschepler
[Boost.MultiIndex] (http://www.boost.org/doc/libs/1_54_0/libs/multi_index/doc/index.html) 여기로가는 방법 – TemplateRex
@aschepler,'begin() '와'end()'iterators는 괜찮지 만, 요청할 때 복사 나 다른 액션을 필요로하지 않는다. – Subway