在C ++编译时

时间:2018-04-11 07:08:49

标签: c++ tree dependent-type

我正在尝试在编译时为C ++提供一些依赖类型的数据结构。我有点解决了主要的例子,一个列表类型,其长度编码类型,又名。 list<T, length>。有一些简单的不变量可以很容易地保存在这里,就像你可以确定附加两个列表将其长度的总和作为长度等。到目前为止琐碎。我现在正在转向依赖类型的树,也就是说。 binary_tree<T, height>,以便我可以修改它以实现高度平衡的树。想法是丢弃任何会在编译时打破高度平衡的操作。对我来说,整个事情也是一种很好的递归思维练习。

我将展示我的尝试,稍后会询问错误。

// A binary tree of height N
template <typename T, std::size_t N>
struct binary_tree
{
    constexpr binary_tree(const T &node, binary_tree<T, N-1> left,
                                         binary_tree<T, N-1> right)
    :root{node}, left{left}, right{right}, size{left.size + right.size + 1}
    {}

    const T root;
    const binary_tree<T, N-1> left;
    const binary_tree<T, N-1> right;
    const std::size_t size; // num of elements in tree
    constexpr static const std::size_t capacity = 2^N -1;
};

template <typename T>
struct binary_tree<T, 0>
{
    const std::size_t size{0};
    constexpr static const bool nil = true;
};

template <typename T>
using empty_tree = binary_tree<T,0>;


template <typename T, std::size_t N>
constexpr auto insert(const T& elem, const binary_tree<T, N> &tree) {
    if constexpr (N == 0)
        return binary_tree<T, 1>{elem, empty_tree<T>{}, empty_tree<T>{}};
    else if (elem <= tree.root && tree.size < binary_tree<T, N>::capacity)
        return binary_tree<T, N>{tree.root, 
                                 insert(elem, tree.left),
                                 tree.right};
    else if (elem <= tree.root && tree.size == binary_tree<T, N>::capacity)
        return binary_tree<T, N + 1>{tree.root, 
                                 insert(elem, tree.left),
                                 tree.right};
    else if (elem > tree.root && tree.size < binary_tree<T, N>::capacity)
        return binary_tree<T, N>{tree.root, 
                                 tree.left,
                                 insert(elem, tree.right)};
    else if (elem > tree.root && tree.size == binary_tree<T, N>::capacity)
        return binary_tree<T, N + 1>{tree.root, 
                                    tree.left,
                                    insert(elem, tree.right)};
}

int main() {
    constexpr binary_tree<int, 1> tr1{2, empty_tree<int>{}, empty_tree<int> {}};
    constexpr auto tr2 = insert(1, tr1);
}

问题是,我的insert函数也试图实例化对其他分支的调用,因为只有第一个是constexpr if。不知何故,我需要将所有情况都设为else if constexpr,但这似乎不可能,因为比较elem以查看要插入的子树不是constexpr。为什么elem < tree.root不是constexpr,毕竟它们是两个常数值。

编辑:我意识到将左右子树带到相同高度是有问题的,对于一般树木不一定是这样。这让我更加困惑。

0 个答案:

没有答案