将两个独立的std::列表相互绑定
tying two separate std::lists to each other
好吧,这是一个奇怪的问题,我不确定是否有解决方案。
我有两个列表,比如客户端列表和每个客户端的一些数据列表。我有兴趣将这两个列表保存在两个单独的std::list
中,因为我有一个API来提供客户端列表,但我不想同时提供其余的数据
然而,由于两个列表应该相互对齐,即每个列表中的元素n应该指向同一个客户端,我正在寻找一种方法来在它们之间进行链接,这样,如果不添加/删除另一个列表中的相应元素,就无法添加/删除一个列表的元素,但为了我提到的API目的,仍然将它们保留在两个单独的列表中。
有什么想法吗?
您可以做一个非常简单的封装
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;
}
如果要设计接口,我会继续将它们放在一个容器中,但为用户提供只允许访问公共客户端部分的自定义迭代器。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
对象进行复制;用户获得对私有列表中相同对象的引用。
这确实在迭代器类型中公开了一个公共base()
成员函数,可能会被讨厌的人用来访问InternalData
。但是,任何知道或发现base()
的人都应该知道或意识到他们不应该使用它。如果这让你担心,你可以私下继承iterator_adaptor
,然后手动将其所有公共成员(base()
除外)再次公开。或者(可能更容易),使InternalData
中的所有内容都是私有的或受保护的,然后使friend
成为您一侧将使用它的类。
相关文章:
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 将std ::列表附加到std ::列表的向量中
- STD ::列表对其分配器参数有什么作用
- swig-包装到c#时,没有默认的std ::列表,我该怎么做
- 调用具有std ::列表为参数的C 函数
- STD ::列表和垃圾收集算法
- 低于20亿的质量 - 使用STD ::列表阻碍性能
- C 按其值对object的std ::列表进行排序
- 如何在(C )构造函数参数列表中包含std:列表
- 如何使用迭代器插入std ::列表
- C STD ::列表分割故障
- 将带有指针的 STD 列表复制到另一个带有指针的 STD 列表
- 比较std::对的2个std::列表
- 在 std 列表中查找对象并将其添加到另一个列表
- 与内存堆有关的C 链接列表(STD ::列表)是否使用新的
- 使用STD ::列表作为循环列表安全吗?
- C++当类型T需要构造函数时,是否可以创建类型T的std::列表
- 从对象指针的 STD 列表中擦除对象
- 如何从std::列表中删除项目
- 正在从std::unique_pointer的std::列表中删除元素