[英]How to define a b+tree-like structure with c++ recursive templates
我正在创建一个类似 b+ 树的数据结构,不同之处在于每个节点级别能够保存不同类型的值(用于缓存目的)并且具有不同数量的子节点。
例如:
我不需要在运行时更改树结构,所以我想使用模板来配置它。 我期望上面示例的实例化看起来像这样:
Tree<StructLeaf, <8, Struct1>, <16, Struct2>, <32, Struct3>>()
和这样的模板定义,这不是实际的代码,只是我认为它可能看起来像这样:
// variadic template recursion 'entrypoint'
template<
typename TLeafData, // do I have to set leaf data before variadic template, even if it is of different structure?
<int TChildrenSize, typename TData>... TChildNodes> // list of pairs of nodes configurations, how to make it a variadic of pairs?
>
class Node;
// template recursion body
template<
typename TLeafData, //same as before
<int TChildrenSize, typename TData> TNode, // values for the current node, how to define a pair?
<int TChildrenSize, typename TData>... TChildNodes> // same as before
>
class Node {
TNode.TData data; // how to access TNode.TData?
std::array<Node<TLeafData, TChildNodes...>, TNode.TChildrenSize> children; // how to pass TChildNodes and access TNode.TChildrenSize?
}
// template recursion end
template<
typename TLeafData, //same as before
<> // empty template to stop recursion, how to define it?
>
class Node {
TLeafData data;
}
我看到如何在没有 TData 的情况下,仅使用 ChildrenSize,通过使用 int 的递归模板来制作这个结构,但我也想知道是否可以或如何将数据类型添加到模板?
我尝试为此使用模板的模板,但看起来它是用于传递对之外的另一个用例,因为我找不到访问内部模板值的方法。
template<template<int A, typename B> typename C>
class AClass {
C.B data; // type B is unaccessable
}
描述这一点的自然递归方式是每个级别只知道下一个级别,例如:
using MyTree = Tree<Struct1, 8,
Tree<Struct2, 16,
Tree<Struct3, 32,
Leaf<StructLeaf>
>
>
>;
可能这应该区分内部节点类型和顶级树,但你明白了。
请注意,您的代码草图不是递归的,而是可变的。 您仍然可以对其进行递归,但这似乎比首先递归地定义它要多得多。
不完全是你问的,但是......一些建议......
strutLead
,就放在模板参数列表的最后一个position,不要放在第一个positionTWrapper
所以你的tree
变量变成
Node<TWrapper<8u, Struct1>, TWrapper<16u, Struct2>,
TWrapper<32u, Struct3>, StructLeaf> tree;
可以实现Node
声明定义TWrapper
template <std::size_t, typename>
struct TWrapper
{ };
并声明Node
如下
// template declaration
template <typename, typename...>
class Node;
作为接收强制类型名和类型名的可变序列
递归情况的声明可以简单地是Node
的特化如下
// recursion case Node
template <std::size_t Dim, typename TData, typename ... Ts>
class Node<TWrapper<Dim, TData>, Ts...>
{
TData data;
std::array<Node<Ts...>, Dim> children;
};
从第一个TWrapper
中获取数组的维度和TData
类型,然后定义以下Node
,只需传递剩余的模板参数即可。
基本情况可以简单地写成Node
的另一个特化如下
// groud case Node
template <typename TData>
class Node<TData>
{
TData data;
};
完整的编译示例如下
#include <array>
template <std::size_t, typename>
struct TWrapper
{ };
// template declaration
template <typename, typename...>
class Node;
// recursion case Node
template <std::size_t Dim, typename TData, typename ... Ts>
class Node<TWrapper<Dim, TData>, Ts...>
{
TData data;
std::array<Node<Ts...>, Dim> children;
};
// groud case Node
template <typename TData>
class Node<TData>
{
TData data;
};
struct Struct1 {};
struct Struct2 {};
struct Struct3 {};
struct StructLeaf {};
int main()
{
Node<TWrapper<8u, Struct1>, TWrapper<16u, Struct2>,
TWrapper<32u, Struct3>, StructLeaf> tree;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.