【发布时间】:2014-11-12 17:30:18
【问题描述】:
我想知道如何实现像boost::mpl::map 这样的模板元编程结构,该结构支持恒定时间插入和删除元素,以及成员资格测试。
>很难在所有变通方法、宏和生成的代码后面的 boost 标头中找到真正的实现。
【问题讨论】:
我想知道如何实现像boost::mpl::map 这样的模板元编程结构,该结构支持恒定时间插入和删除元素,以及成员资格测试。
>很难在所有变通方法、宏和生成的代码后面的 boost 标头中找到真正的实现。
【问题讨论】:
基本上,通过巧妙地使用重载。假设您想构建一个只有两个“元素”的地图:T --> U 和 X --> Y。如果我们展平所有继承层次结构,我们最终会得到一个看起来像这样的类型:
struct specific_mpl_map {
U get(T );
Y get(X );
template <typename AnythingElse>
void_ get(AnythingElse );
pair<T, U> get(int_<0> );
pair<X, Y> get(int_<1> );
using size = int_<2>;
};
这样,查找某个键 K 将只是 decltype(map.get(K{})),它是编译时常量 - 您无需遍历所有对来找出有一个 get(K)。而且您还拥有一种按顺序迭代的机制,只需调用get(int_<i>{})。任何插入/删除只会创建一个新的映射类型,其中包含所有新的预期 get() 函数。
这并不是代码的样子,实际上每个get 都有自己的类型,并且对于您添加到地图的每个pair,整个事情都是线性继承的,但这大约是最终目标是。
如果你用-E 编译然后看看什么被丢弃了,这会很有帮助。键类型称为m_item,它为每种查找类型定义了静态函数。所以如果我们想通过key进行查找,有:
template< typename Key, typename T, typename Base >
struct m_item
: Base // Base is the rest of the map less this element
{
// some typedefs
static aux::type_wrapper<T> value_by_key_(m_item const&,
aux::type_wrapper<Key>*);
using Base::value_by_key_;
};
at 如此使用:
template< typename Map, typename Key >
struct m_at
{
typedef aux::type_wrapper<Key> key_;
typedef __typeof__( Map::value_by_key_(
aux::ptr_to_ref(static_cast<Map*>(0)),
static_cast<key_*>(0) )
) type;
};
基本空地图还定义了:
template< typename Dummy = na > struct map0
{
static aux::type_wrapper<void_> value_by_key_(map0<> const&,
void const volatile*);
};
【讨论】: